From 8a1977dc63bcb6377aec45580fa076e5662879ec Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 10:18:13 -0800 Subject: [PATCH 01/11] [Sema] Move the computaton of the context type of 'self' later. We cannot properly determine the context type of any parameter (including 'self') until after we have determined the generic environment for the enclosing function. --- lib/Parse/ParseDecl.cpp | 1 - lib/Sema/TypeCheckDecl.cpp | 48 ++++++++++++++++++++++++++++++---- test/decl/var/properties.swift | 2 +- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index c1b86b38cd99a..be445e59d65e9 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -3827,7 +3827,6 @@ void Parser::ParsedAccessors::record(Parser &P, AbstractStorageDecl *storage, SmallVectorImpl &decls) { auto flagInvalidAccessor = [&](FuncDecl *&func) { if (func) { - func->setInterfaceType(ErrorType::get(P.Context)); func->setInvalid(); } }; diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 1b1e1d9d6ea45..53849748ba437 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -1123,12 +1123,15 @@ static void configureImplicitSelf(TypeChecker &tc, selfDecl->setLet(!selfIfaceTy->is()); selfDecl->setInterfaceType(selfIfaceTy); +} - // FIXME: Wrong DeclContext used for mapTypeIntoContext(), because - // 'func' doesn't have a generic environment yet. +/// Record the context type of 'self' after the generic environment of +/// the function has been determined. +static void recordSelfContextType(AbstractFunctionDecl *func) { + auto selfDecl = func->getImplicitSelfDecl(); Type selfTy = func->computeInterfaceSelfType(/*isInitializingCtor*/true, /*wantDynamicSelf*/true); - selfTy = func->getDeclContext()->mapTypeIntoContext(selfTy); + selfTy = func->mapTypeIntoContext(selfTy); selfDecl->setType(selfTy); } @@ -4797,6 +4800,10 @@ class DeclChecker : public DeclVisitor { } } + // Set the context type of 'self'. + if (FD->getDeclContext()->isTypeContext()) + recordSelfContextType(FD); + // Type check the parameters and return type again, now with archetypes. GenericTypeToArchetypeResolver resolver(FD); if (semaFuncDecl(FD, resolver)) @@ -6417,6 +6424,9 @@ class DeclChecker : public DeclVisitor { CD->getDeclContext()->getGenericEnvironmentOfContext()); } + // Set the context type of 'self'. + recordSelfContextType(CD); + { CD->setIsBeingTypeChecked(true); SWIFT_DEFER { CD->setIsBeingTypeChecked(false); }; @@ -6568,6 +6578,9 @@ class DeclChecker : public DeclVisitor { DD->getDeclContext()->getGenericEnvironmentOfContext()); } + // Set the context type of 'self'. + recordSelfContextType(DD); + GenericTypeToArchetypeResolver resolver(DD); if (semaFuncParamPatterns(DD, resolver)) { DD->setInterfaceType(ErrorType::get(TC.Context)); @@ -6825,6 +6838,25 @@ void TypeChecker::checkDeclCircularity(NominalTypeDecl *decl) { } } +/// Determine whether the given variable is the implicit 'self' parameter for +/// a function, and return that function if so. +static AbstractFunctionDecl *isImplicitSelfParam(VarDecl *var){ + if (!var->isImplicit()) return nullptr; + + auto param = dyn_cast(var); + if (!param) return nullptr; + + auto func = dyn_cast(var->getDeclContext()); + if (!func) return nullptr; + + if (!func->getDeclContext()->isTypeContext()) return nullptr; + + if (param == func->getImplicitSelfDecl()) + return func; + + return nullptr; +} + void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { if (hasEnabledForbiddenTypecheckPrefix()) checkForForbiddenPrefix(D); @@ -7063,12 +7095,18 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { ValidatedTypes.insert(proto); break; } - + case DeclKind::Var: case DeclKind::Param: { auto VD = cast(D); if (!VD->hasType()) { - if (PatternBindingDecl *PBD = VD->getParentPatternBinding()) { + if (auto func = isImplicitSelfParam(VD)) { + if (!VD->hasInterfaceType()) { + VD->setInterfaceType(ErrorType::get(Context)); + VD->setInvalid(); + } + recordSelfContextType(func); + } else if (PatternBindingDecl *PBD = VD->getParentPatternBinding()) { if (PBD->isBeingTypeChecked()) { diagnose(VD, diag::pattern_used_in_type, VD->getName()); diff --git a/test/decl/var/properties.swift b/test/decl/var/properties.swift index 1aa4e820d77db..604248c7ef9e4 100644 --- a/test/decl/var/properties.swift +++ b/test/decl/var/properties.swift @@ -268,7 +268,7 @@ var computed_prop_with_init_1: X { // FIXME: Redundant error below var x2 { // expected-error{{computed property must have an explicit type}} expected-error{{type annotation missing in pattern}} get { - return _x + return _x // expected-error{{unexpected non-void return value in void function}} } } From 37bb4d1eae650a2a58e8dc897eede57e64a311e4 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 11:55:59 -0800 Subject: [PATCH 02/11] [AST] Make typealiases not "type contexts" DeclContext's nomenclature around "type contexts" is confusing, because it essentially means "nominal type contexts", e.g., struct/class/enum/protocol and extensions thereof. This implies the presence of a 'Self' type, the ability to have members, etc. However, typealiases are also currently classified as "type contexts", despite not having a reasonable 'Self' type, which breaks in various places. Stop classifying typealiases as "type contexts". --- include/swift/AST/DeclContext.h | 5 +---- lib/AST/DeclContext.cpp | 14 +++++++++++++- lib/AST/NameLookup.cpp | 3 ++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h index e1208c307098e..376f5534998d2 100644 --- a/include/swift/AST/DeclContext.h +++ b/include/swift/AST/DeclContext.h @@ -232,10 +232,7 @@ 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 { diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp index 590fac1eed69f..a9cd24534f945 100644 --- a/lib/AST/DeclContext.cpp +++ b/lib/AST/DeclContext.cpp @@ -357,6 +357,12 @@ AbstractFunctionDecl *DeclContext::getInnermostMethodContext() { } } +bool DeclContext::isTypeContext() const { + return (getContextKind() == DeclContextKind::GenericTypeDecl && + !isa(this)) || + getContextKind() == DeclContextKind::ExtensionDecl; +} + DeclContext *DeclContext::getInnermostTypeContext() { DeclContext *Result = this; while (true) { @@ -374,8 +380,14 @@ DeclContext *DeclContext::getInnermostTypeContext() { case DeclContextKind::FileUnit: return nullptr; - case DeclContextKind::ExtensionDecl: case DeclContextKind::GenericTypeDecl: + if (isa(Result)) { + Result = Result->getParent(); + continue; + } + return Result; + + case DeclContextKind::ExtensionDecl: return Result; } } diff --git a/lib/AST/NameLookup.cpp b/lib/AST/NameLookup.cpp index b62a28f1d6c32..a011f11106263 100644 --- a/lib/AST/NameLookup.cpp +++ b/lib/AST/NameLookup.cpp @@ -787,7 +787,8 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC, DC = I->getParent()->getParent(); continue; } else { - assert(isa(DC) || isa(DC)); + assert(isa(DC) || isa(DC) || + isa(DC)); if (!isCascadingUse.hasValue()) isCascadingUse = DC->isCascadingContextForLookup(false); } From d590f2e83db420a6d75a450e7f8f6eddf041fd99 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 11:56:29 -0800 Subject: [PATCH 03/11] [Sema/AST] Type-check typealiases within their own context. Typealiases were getting type-checked in their parent's context, not their own context. For non-generic typealiases this is fine, because the generic environment is inherited. Generic typealiases, on the other hand, have their own generic environment that should be used. Do so. --- lib/Sema/TypeCheckDecl.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 53849748ba437..7d8131323214d 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -3881,8 +3881,7 @@ class DeclChecker : public DeclVisitor { if (TAD->getDeclContext()->isModuleScopeContext()) { IterativeTypeChecker ITC(TC); ITC.satisfy(requestResolveTypeDecl(TAD)); - } else if (TC.validateType(TAD->getUnderlyingTypeLoc(), - TAD->getDeclContext(), options)) { + } else if (TC.validateType(TAD->getUnderlyingTypeLoc(), TAD, options)) { TAD->setInvalid(); TAD->setInterfaceType(ErrorType::get(TC.Context)); TAD->getUnderlyingTypeLoc().setInvalidType(TC.Context); From 38671e27719bae26442bbdb182904ef8a3572dd0 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 12:01:14 -0800 Subject: [PATCH 04/11] [AST] Hide DeclContext::getAsGenericTypeOrGenericTypeExtensionContext(). This method gets the GenericTypeDecl for a typealias, nominal type, or extension thereof. While the result is typed as GenericTypeDecl, it's not always generic, so rename it accordingly. An audit of the callers illustrated that they should be using different entrypoints anyway, so fix all of the callers and make this function private. --- include/swift/AST/DeclContext.h | 10 +++++----- lib/AST/ConformanceLookupTable.cpp | 3 +-- lib/AST/DeclContext.cpp | 16 ++++++---------- lib/IDE/CodeCompletion.cpp | 6 +++--- lib/Sema/CSApply.cpp | 2 +- lib/Sema/CSDiag.cpp | 4 ++-- lib/Sema/TypeCheckProtocol.cpp | 3 +-- 7 files changed, 19 insertions(+), 25 deletions(-) diff --git a/include/swift/AST/DeclContext.h b/include/swift/AST/DeclContext.h index 376f5534998d2..a5e9c57d5ca2b 100644 --- a/include/swift/AST/DeclContext.h +++ b/include/swift/AST/DeclContext.h @@ -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) { @@ -239,10 +243,6 @@ class alignas(1 << DeclContextAlignInBits) DeclContext { 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; diff --git a/lib/AST/ConformanceLookupTable.cpp b/lib/AST/ConformanceLookupTable.cpp index dc9ef3c112b90..1d72183ae718a 100644 --- a/lib/AST/ConformanceLookupTable.cpp +++ b/lib/AST/ConformanceLookupTable.cpp @@ -801,8 +801,7 @@ ProtocolConformance *ConformanceLookupTable::getConformance( return nullptr; auto *conformingNominal = - cast(conformingDC-> - getAsGenericTypeOrGenericTypeExtensionContext()); + conformingDC->getAsNominalTypeOrNominalTypeExtensionContext(); // Form the conformance. Type type = entry->getDeclContext()->getDeclaredTypeInContext(); diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp index a9cd24534f945..f8526c32714f1 100644 --- a/lib/AST/DeclContext.cpp +++ b/lib/AST/DeclContext.cpp @@ -40,7 +40,7 @@ ASTContext &DeclContext::getASTContext() const { } GenericTypeDecl * -DeclContext::getAsGenericTypeOrGenericTypeExtensionContext() const { +DeclContext::getAsTypeOrTypeExtensionContext() const { switch (getContextKind()) { case DeclContextKind::Module: case DeclContextKind::FileUnit: @@ -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(decl); } ClassDecl *DeclContext::getAsClassOrClassExtensionContext() const { - return dyn_cast_or_null( - getAsGenericTypeOrGenericTypeExtensionContext()); + return dyn_cast_or_null(getAsTypeOrTypeExtensionContext()); } EnumDecl *DeclContext::getAsEnumOrEnumExtensionContext() const { - return dyn_cast_or_null( - getAsGenericTypeOrGenericTypeExtensionContext()); + return dyn_cast_or_null(getAsTypeOrTypeExtensionContext()); } ProtocolDecl *DeclContext::getAsProtocolOrProtocolExtensionContext() const { - return dyn_cast_or_null( - getAsGenericTypeOrGenericTypeExtensionContext()); + return dyn_cast_or_null(getAsTypeOrTypeExtensionContext()); } ProtocolDecl *DeclContext::getAsProtocolExtensionContext() const { if (getContextKind() != DeclContextKind::ExtensionDecl) return nullptr; - return dyn_cast_or_null( - getAsGenericTypeOrGenericTypeExtensionContext()); + return dyn_cast_or_null(getAsTypeOrTypeExtensionContext()); } GenericTypeParamType *DeclContext::getProtocolSelfType() const { diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index 63ff9003d6792..95baeddec610d 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -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. @@ -4309,7 +4309,7 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer { } void getOverrideCompletions(SourceLoc Loc) { - if (!CurrDeclContext->getAsGenericTypeOrGenericTypeExtensionContext()) + if (!CurrDeclContext->getAsNominalTypeOrNominalTypeExtensionContext()) return; Type CurrTy = CurrDeclContext->getDeclaredTypeInContext(); diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index a6e44a0e00e77..c7d01f8eb2891 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -704,7 +704,7 @@ namespace { if (!isa(fn)) return false; auto *parent = - fn->getParent()->getAsGenericTypeOrGenericTypeExtensionContext(); + fn->getParent()->getAsNominalTypeOrNominalTypeExtensionContext(); return parent && (isa(parent) || isa(parent)); } diff --git a/lib/Sema/CSDiag.cpp b/lib/Sema/CSDiag.cpp index 462947f8a9094..692e783e56850 100644 --- a/lib/Sema/CSDiag.cpp +++ b/lib/Sema/CSDiag.cpp @@ -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(); diff --git a/lib/Sema/TypeCheckProtocol.cpp b/lib/Sema/TypeCheckProtocol.cpp index 2fef9b5ae3172..f16534016cb00 100644 --- a/lib/Sema/TypeCheckProtocol.cpp +++ b/lib/Sema/TypeCheckProtocol.cpp @@ -2349,8 +2349,7 @@ static void diagnoseNoWitness(ValueDecl *Requirement, Type RequirementType, Accessibility Access = std::min( /* Access of the context */ - Adopter - ->getAsGenericTypeOrGenericTypeExtensionContext()->getFormalAccess(), + Adopter->getAsNominalTypeOrNominalTypeExtensionContext()->getFormalAccess(), /* Access of the protocol */ Requirement->getDeclContext() ->getAsProtocolOrProtocolExtensionContext()->getFormalAccess()); From 7349dca8dd4fec82aa1c86c4d606c3951a12a8e0 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 15:37:08 -0800 Subject: [PATCH 05/11] [Type checker] Eliminate most uses of PartialGenericTypeToArchetypeResolver. PartialGenericTypeToArchetypeResolver is (eventually) going away. Isolate it's use to those places where we still rely on its odd behavior. --- lib/Sema/ITCDecl.cpp | 5 +++-- lib/Sema/TypeCheckDecl.cpp | 8 ++++++-- lib/Sema/TypeCheckGeneric.cpp | 4 +++- lib/Sema/TypeCheckType.cpp | 9 ++++++--- lib/Sema/TypeChecker.cpp | 11 +++-------- 5 files changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/Sema/ITCDecl.cpp b/lib/Sema/ITCDecl.cpp index 241d969da66c9..e51bb79a303fd 100644 --- a/lib/Sema/ITCDecl.cpp +++ b/lib/Sema/ITCDecl.cpp @@ -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->getGenericEnvironmentOfContext()); if (TC.validateType(*inherited, dc, options, &resolver)) { inherited->setInvalidType(getASTContext()); } @@ -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)) { typeAliasDecl->setInvalid(); typeAliasDecl->setInterfaceType(ErrorType::get(getASTContext())); typeAliasDecl->getUnderlyingTypeLoc().setInvalidType(getASTContext()); diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 7d8131323214d..2312f0d0b96ab 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -295,7 +295,9 @@ void TypeChecker::checkInheritanceClause(Decl *decl, } // Establish a default generic type resolver. - PartialGenericTypeToArchetypeResolver defaultResolver; + auto genericEnv = + decl->getInnermostDeclContext()->getGenericEnvironmentOfContext(); + GenericTypeToArchetypeResolver defaultResolver(genericEnv); if (!resolver) resolver = &defaultResolver; @@ -7419,7 +7421,9 @@ checkExtensionGenericParams(TypeChecker &tc, ExtensionDecl *ext, Type type, // Validate the generic parameters for the last time. tc.revertGenericParamList(genericParams); ArchetypeBuilder builder = tc.createArchetypeBuilder(ext->getModuleContext()); - tc.checkGenericParamList(&builder, genericParams, parentSig, parentEnv, nullptr); + PartialGenericTypeToArchetypeResolver resolver; + tc.checkGenericParamList(&builder, genericParams, parentSig, parentEnv, + &resolver); inferExtendedTypeReqs(builder); auto *env = builder.getGenericEnvironment(sig); diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index 657b29daeb3d3..b82a822063c3a 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -898,7 +898,9 @@ void TypeChecker::validateGenericTypeSignature(GenericTypeDecl *typeDecl) { createArchetypeBuilder(typeDecl->getModuleContext()); auto *parentSig = dc->getGenericSignatureOfContext(); auto *parentEnv = dc->getGenericEnvironmentOfContext(); - checkGenericParamList(&builder, gp, parentSig, parentEnv, nullptr); + + DependentGenericTypeResolver resolver(builder); + checkGenericParamList(&builder, gp, parentSig, parentEnv, &resolver); auto *env = builder.getGenericEnvironment(sig); typeDecl->setGenericEnvironment(env); diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index 5b8e224486a90..d5e6cf0cc7db8 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -201,7 +201,8 @@ Type TypeChecker::resolveTypeInContext( bool isSpecialized, GenericTypeResolver *resolver, UnsatisfiedDependency *unsatisfiedDependency) { - PartialGenericTypeToArchetypeResolver defaultResolver; + GenericTypeToArchetypeResolver defaultResolver( + fromDC->getGenericEnvironmentOfContext()); if (!resolver) resolver = &defaultResolver; @@ -528,7 +529,8 @@ Type TypeChecker::applyUnboundGenericArguments( "invalid arguments, use applyGenericArguments for diagnostic emitting"); // Make sure we always have a resolver to use. - PartialGenericTypeToArchetypeResolver defaultResolver; + GenericTypeToArchetypeResolver defaultResolver( + dc->getGenericEnvironmentOfContext()); if (!resolver) resolver = &defaultResolver; @@ -1611,7 +1613,8 @@ Type TypeChecker::resolveType(TypeRepr *TyR, DeclContext *DC, PrettyStackTraceTypeRepr stackTrace(Context, "resolving", TyR); // Make sure we always have a resolver to use. - PartialGenericTypeToArchetypeResolver defaultResolver; + GenericTypeToArchetypeResolver defaultResolver( + DC->getGenericEnvironmentOfContext()); if (!resolver) resolver = &defaultResolver; diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp index 0787c376fff85..f4fa2fffba7df 100644 --- a/lib/Sema/TypeChecker.cpp +++ b/lib/Sema/TypeChecker.cpp @@ -715,20 +715,15 @@ bool swift::performTypeLocChecking(ASTContext &Ctx, TypeLoc &T, if (isSILType) options |= TR_SILType; - // FIXME: Get rid of PartialGenericTypeToArchetypeResolver GenericTypeToArchetypeResolver contextResolver(GenericEnv); - PartialGenericTypeToArchetypeResolver defaultResolver; - - GenericTypeResolver *resolver = - (GenericEnv ? (GenericTypeResolver *) &contextResolver - : (GenericTypeResolver *) &defaultResolver); if (ProduceDiagnostics) { - return TypeChecker(Ctx).validateType(T, DC, options, resolver); + return TypeChecker(Ctx).validateType(T, DC, options, &contextResolver); } else { // Set up a diagnostics engine that swallows diagnostics. DiagnosticEngine Diags(Ctx.SourceMgr); - return TypeChecker(Ctx, Diags).validateType(T, DC, options, resolver); + return TypeChecker(Ctx, Diags).validateType(T, DC, options, + &contextResolver); } } From 3184d8463821a26d99d2328022f1505a83800ece Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 16:08:05 -0800 Subject: [PATCH 06/11] [Type checker] Eliminate use of PartialGenericTypeToArchetypeResolver. Stop using PartialGenericTypeToArchetypeResolver in extensions. It means Yet Another ArchetypeBuilder pass (for now). --- lib/Sema/TypeCheckDecl.cpp | 18 ++++++++++++++---- test/Generics/same_type_constraints.swift | 1 - test/decl/ext/generic.swift | 2 +- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 2312f0d0b96ab..2ea9c0aa7b354 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -7418,18 +7418,28 @@ checkExtensionGenericParams(TypeChecker &tc, ExtensionDecl *ext, Type type, /*allowConcreteGenericParams=*/true, inferExtendedTypeReqs); - // Validate the generic parameters for the last time. + // Validate the generic parameters for the penultimate time to get an + // environment where we have the parent archetypes. tc.revertGenericParamList(genericParams); ArchetypeBuilder builder = tc.createArchetypeBuilder(ext->getModuleContext()); - PartialGenericTypeToArchetypeResolver resolver; + DependentGenericTypeResolver completeResolver(builder); tc.checkGenericParamList(&builder, genericParams, parentSig, parentEnv, - &resolver); + &completeResolver); inferExtendedTypeReqs(builder); + (void)builder.finalize(genericParams->getSourceRange().Start, + /*allowConcreteGenericParams=*/true); auto *env = builder.getGenericEnvironment(sig); - tc.recordArchetypeContexts(sig, env, ext); + // Validate the generic parameters for the last time, to splat down + // actual archetypes. + tc.revertGenericParamList(genericParams); + GenericTypeToArchetypeResolver archetypeResolver(env); + tc.checkGenericParamList(nullptr, genericParams, parentSig, parentEnv, + &archetypeResolver); + + // Compute the final extended type. Type resultType; diff --git a/test/Generics/same_type_constraints.swift b/test/Generics/same_type_constraints.swift index 0030cf61d2ab8..a5801b25dad41 100644 --- a/test/Generics/same_type_constraints.swift +++ b/test/Generics/same_type_constraints.swift @@ -329,7 +329,6 @@ protocol P9 { struct X7 where T.A : C { } extension X7 where T.A == Int { } // expected-error 2{{'T.A' requires that 'Int' inherit from 'C'}} - struct X8 { } extension X8 where T == Int { } // expected-error 2{{'T' requires that 'Int' inherit from 'C'}} diff --git a/test/decl/ext/generic.swift b/test/decl/ext/generic.swift index 4bf1a79b6f6b8..a70281dbcca1e 100644 --- a/test/decl/ext/generic.swift +++ b/test/decl/ext/generic.swift @@ -151,4 +151,4 @@ struct S4: P4 { init(_: Q) { } } -extension S4 where T : P5 {} // expected-error{{type 'T' in conformance requirement does not refer to a generic parameter or associated type}} +extension S4 where T : P5 {} From 39eeb1343d37b0394dfe60273db3e31cbc721861 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 16:34:15 -0800 Subject: [PATCH 07/11] [Type checker] Eliminate SIL parser's use of PartialGenericTypeToArchetypeResolver. --- lib/Sema/TypeCheckDecl.cpp | 9 ++++++++- lib/Sema/TypeChecker.h | 4 ++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 2ea9c0aa7b354..2c084978e5544 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -732,11 +732,18 @@ TypeChecker::handleSILGenericParams(GenericParamList *genericParams, revertGenericParamList(genericParams); ArchetypeBuilder builder(*DC->getParentModule()); + CompleteGenericTypeResolver completeResolver(*this, builder); checkGenericParamList(&builder, genericParams, parentSig, parentEnv, - nullptr); + &completeResolver); parentSig = genericSig; parentEnv = builder.getGenericEnvironment(parentSig); recordArchetypeContexts(parentSig, parentEnv, DC); + + // Compute the final set of archetypes. + revertGenericParamList(genericParams); + GenericTypeToArchetypeResolver archetypeResolver(parentEnv); + checkGenericParamList(nullptr, genericParams, parentSig, parentEnv, + &archetypeResolver); } return parentEnv; diff --git a/lib/Sema/TypeChecker.h b/lib/Sema/TypeChecker.h index 695f8156ca9cd..8c512d382a05e 100644 --- a/lib/Sema/TypeChecker.h +++ b/lib/Sema/TypeChecker.h @@ -726,7 +726,7 @@ class TypeChecker final : public LazyResolver { /// \param options Options that alter type resolution. /// /// \param resolver A resolver for generic types. If none is supplied, this - /// routine will create a \c PartialGenericTypeToArchetypeResolver to use. + /// routine will create a \c GenericTypeToArchetypeResolver to use. /// /// \returns true if type validation failed, or false otherwise. bool validateType(TypeLoc &Loc, DeclContext *DC, @@ -756,7 +756,7 @@ class TypeChecker final : public LazyResolver { /// \param options Options that alter type resolution. /// /// \param resolver A resolver for generic types. If none is supplied, this - /// routine will create a \c PartialGenericTypeToArchetypeResolver to use. + /// routine will create a \c GenericTypeToArchetypeResolver to use. /// /// \param unsatisfiedDependency When non-null, used to check whether /// dependencies have been satisfied appropriately. From 13e17147798fd3fdc17a53aabf4fe6450eb7c91e Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 16:55:11 -0800 Subject: [PATCH 08/11] Remove PartialGenericTypeToArchetypeResolver. --- lib/Sema/GenericTypeResolver.h | 29 --------------- lib/Sema/TypeCheckGeneric.cpp | 66 ---------------------------------- 2 files changed, 95 deletions(-) diff --git a/lib/Sema/GenericTypeResolver.h b/lib/Sema/GenericTypeResolver.h index 1ae12eeeb3406..fb06dc945b4f6 100644 --- a/lib/Sema/GenericTypeResolver.h +++ b/lib/Sema/GenericTypeResolver.h @@ -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. /// diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index b82a822063c3a..76e84a06afb42 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -149,72 +149,6 @@ void GenericTypeToArchetypeResolver::recordParamType(ParamDecl *decl, Type type) type)); } -Type PartialGenericTypeToArchetypeResolver::resolveGenericTypeParamType( - GenericTypeParamType *gp) { - auto gpDecl = gp->getDecl(); - if (!gpDecl) - return Type(gp); - - // Hack: See parseGenericParameters(). When the issue there is fixed, - // we won't need the isInvalid() check anymore. - if (gpDecl->isInvalid()) - return ErrorType::get(gpDecl->getASTContext()); - - if (!gpDecl->getDeclContext()->isValidGenericContext()) - return Type(gp); - - auto *genericEnv = gpDecl->getDeclContext()->getGenericEnvironmentOfContext(); - return genericEnv->mapTypeIntoContext(gp); -} - -Type PartialGenericTypeToArchetypeResolver::resolveDependentMemberType( - Type baseTy, - DeclContext *DC, - SourceRange baseRange, - ComponentIdentTypeRepr *ref) { - // We don't have enough information to find the associated type. - // FIXME: Nonsense, but we shouldn't need this code anyway. - return DependentMemberType::get(baseTy, ref->getIdentifier()); -} - -Type PartialGenericTypeToArchetypeResolver::resolveSelfAssociatedType( - Type selfTy, - DeclContext *DC, - AssociatedTypeDecl *assocType) { - // We don't have enough information to find the associated type. - // FIXME: Nonsense, but we shouldn't need this code anyway. - return DependentMemberType::get(selfTy, assocType); -} - -Type -PartialGenericTypeToArchetypeResolver::resolveTypeOfContext(DeclContext *dc, - bool wantSelf) { - if (dc->isGenericContext() && dc->isValidGenericContext()) - return dc->mapTypeIntoContext(getTypeOfContext(dc, wantSelf)); - return getTypeOfContext(dc, wantSelf); -} - -Type -PartialGenericTypeToArchetypeResolver::resolveTypeOfDecl(TypeDecl *decl) { - // Hack for 'out of context' GenericTypeParamDecls when resolving - // a generic typealias - if (auto *paramDecl = dyn_cast(decl)) { - return decl->getDeclContext()->getGenericEnvironmentOfContext() - ->mapTypeIntoContext(paramDecl->getDeclaredInterfaceType() - ->castTo()); - } - - auto *aliasDecl = cast(decl); - if (aliasDecl->isInvalid()) - return ErrorType::get(aliasDecl->getASTContext()); - return aliasDecl->getAliasType(); -} - -void -PartialGenericTypeToArchetypeResolver::recordParamType(ParamDecl *decl, Type type) { - // Do nothing -} - Type CompleteGenericTypeResolver::resolveGenericTypeParamType( GenericTypeParamType *gp) { auto gpDecl = gp->getDecl(); From 6c7277be2cf48b2f2ffa1c39b56c7135d6f09de1 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 22:34:12 -0800 Subject: [PATCH 09/11] [Type checker] Work around issues with badly broken generic code. The GenericTypeOrArchetypeResolver changes are effectively porting some existing hacks from the now-dead PartialGenericTypeOrArchetypeResolver, which dodges some regressions in the compiler-crashers suite and fixes 11 new crashers. There is undoubtedly a more principled approach to fix these problems, most of which now step from recursively looking for a generic environment that isn't there, but doing so requires improvements to our name lookup. --- lib/Sema/TypeCheckDecl.cpp | 4 ++++ lib/Sema/TypeCheckGeneric.cpp | 13 +++++++++---- .../032-swift-expr-propagatelvalueaccesskind.swift | 1 - ...28209-swift-protocoldecl-requiresclassslow.swift | 2 +- .../28351-swift-functiontype-get.swift | 2 +- ...erictyperesolver-resolveselfassociatedtype.swift | 2 +- ...8-swift-typechecker-checkinheritanceclause.swift | 2 +- .../28423-swift-typechecker-validatedecl.swift | 2 +- ...wift-genericenvironment-maptypeintocontext.swift | 2 +- ...pemap-end-missing-generic-parameter-failed.swift | 2 +- ...b.swift~13e17147798fd3fdc17a53aabf4fe6450eb7c91e | 9 +++++++++ ...cked-swift-type-llvm-smallptrset-swift-arc.swift | 2 +- ...alarchetype-gettype-swift-archetypebuilder.swift | 2 +- 13 files changed, 31 insertions(+), 14 deletions(-) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28209-swift-protocoldecl-requiresclassslow.swift (79%) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28351-swift-functiontype-get.swift (87%) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28392-swift-dependentgenerictyperesolver-resolveselfassociatedtype.swift (89%) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28408-swift-typechecker-checkinheritanceclause.swift (89%) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28423-swift-typechecker-validatedecl.swift (88%) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28435-swift-genericenvironment-maptypeintocontext.swift (88%) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28453-found-interfacetoarchetypemap-end-missing-generic-parameter-failed.swift (89%) create mode 100644 validation-test/compiler_crashers_fixed/28466-segfault-0xc27624-0xc2741f-0xc25bb5-0xbcdbbb.swift~13e17147798fd3fdc17a53aabf4fe6450eb7c91e rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28471-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift (88%) rename validation-test/{compiler_crashers => compiler_crashers_fixed}/28545-swift-archetypebuilder-potentialarchetype-gettype-swift-archetypebuilder.swift (87%) diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 2c084978e5544..8f3f4002d0f0e 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -7050,6 +7050,10 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { return; proto->computeType(); + auto iBTC = proto->isBeingTypeChecked(); + proto->setIsBeingTypeChecked(); + SWIFT_DEFER { proto->setIsBeingTypeChecked(iBTC); }; + // Resolve the inheritance clauses for each of the associated // types. for (auto member : proto->getMembers()) { diff --git a/lib/Sema/TypeCheckGeneric.cpp b/lib/Sema/TypeCheckGeneric.cpp index 76e84a06afb42..c17b9bf328d2d 100644 --- a/lib/Sema/TypeCheckGeneric.cpp +++ b/lib/Sema/TypeCheckGeneric.cpp @@ -87,13 +87,14 @@ Type GenericTypeToArchetypeResolver::resolveGenericTypeParamType( // Hack: See parseGenericParameters(). When the issue there is fixed, // we won't need the isInvalid() check anymore. - if (gpDecl->isInvalid()) + if (gpDecl->isInvalid() || !GenericEnv) return ErrorType::get(gpDecl->getASTContext()); - if (auto *Env = GenericEnv) - return Env->mapTypeIntoContext(gp); + auto type = GenericEnv->getMappingIfPresent(gp); + if (!type) + return ErrorType::get(gpDecl->getASTContext());; - return ErrorType::get(gpDecl->getASTContext()); + return *type; } Type GenericTypeToArchetypeResolver::resolveDependentMemberType( @@ -113,6 +114,10 @@ Type GenericTypeToArchetypeResolver::resolveSelfAssociatedType( Type GenericTypeToArchetypeResolver::resolveTypeOfContext(DeclContext *dc, bool wantSelf) { + // FIXME: Fallback case. + if (dc->isGenericContext() && !dc->isValidGenericContext()) + return getTypeOfContext(dc, wantSelf); + return ArchetypeBuilder::mapTypeIntoContext( dc->getParentModule(), GenericEnv, getTypeOfContext(dc, wantSelf)); diff --git a/validation-test/IDE/crashers/032-swift-expr-propagatelvalueaccesskind.swift b/validation-test/IDE/crashers/032-swift-expr-propagatelvalueaccesskind.swift index f7bf01e7ca10e..7166355870978 100644 --- a/validation-test/IDE/crashers/032-swift-expr-propagatelvalueaccesskind.swift +++ b/validation-test/IDE/crashers/032-swift-expr-propagatelvalueaccesskind.swift @@ -1,3 +1,2 @@ // RUN: not --crash %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s -// REQUIRES: asserts {()=(var a{#^A^# diff --git a/validation-test/compiler_crashers/28209-swift-protocoldecl-requiresclassslow.swift b/validation-test/compiler_crashers_fixed/28209-swift-protocoldecl-requiresclassslow.swift similarity index 79% rename from validation-test/compiler_crashers/28209-swift-protocoldecl-requiresclassslow.swift rename to validation-test/compiler_crashers_fixed/28209-swift-protocoldecl-requiresclassslow.swift index 96632c787838c..6722f2ecdf875 100644 --- a/validation-test/compiler_crashers/28209-swift-protocoldecl-requiresclassslow.swift +++ b/validation-test/compiler_crashers_fixed/28209-swift-protocoldecl-requiresclassslow.swift @@ -1,4 +1,4 @@ -// RUN: not --crash %target-swift-frontend %s -typecheck +// RUN: not %target-swift-frontend %s -typecheck // REQUIRES: asserts // Distributed under the terms of the MIT license diff --git a/validation-test/compiler_crashers/28351-swift-functiontype-get.swift b/validation-test/compiler_crashers_fixed/28351-swift-functiontype-get.swift similarity index 87% rename from validation-test/compiler_crashers/28351-swift-functiontype-get.swift rename to validation-test/compiler_crashers_fixed/28351-swift-functiontype-get.swift index ddfbc85ec5529..cebd12d520ec6 100644 --- a/validation-test/compiler_crashers/28351-swift-functiontype-get.swift +++ b/validation-test/compiler_crashers_fixed/28351-swift-functiontype-get.swift @@ -5,5 +5,5 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -typecheck +// RUN: not %target-swift-frontend %s -typecheck extension A{{}protocol A}protocol A:class{protocol A{}typealias e:A diff --git a/validation-test/compiler_crashers/28392-swift-dependentgenerictyperesolver-resolveselfassociatedtype.swift b/validation-test/compiler_crashers_fixed/28392-swift-dependentgenerictyperesolver-resolveselfassociatedtype.swift similarity index 89% rename from validation-test/compiler_crashers/28392-swift-dependentgenerictyperesolver-resolveselfassociatedtype.swift rename to validation-test/compiler_crashers_fixed/28392-swift-dependentgenerictyperesolver-resolveselfassociatedtype.swift index 545651a9cf3c6..54a182bef1213 100644 --- a/validation-test/compiler_crashers/28392-swift-dependentgenerictyperesolver-resolveselfassociatedtype.swift +++ b/validation-test/compiler_crashers_fixed/28392-swift-dependentgenerictyperesolver-resolveselfassociatedtype.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -typecheck +// RUN: not %target-swift-frontend %s -typecheck // REQUIRES: asserts { class A{ diff --git a/validation-test/compiler_crashers/28408-swift-typechecker-checkinheritanceclause.swift b/validation-test/compiler_crashers_fixed/28408-swift-typechecker-checkinheritanceclause.swift similarity index 89% rename from validation-test/compiler_crashers/28408-swift-typechecker-checkinheritanceclause.swift rename to validation-test/compiler_crashers_fixed/28408-swift-typechecker-checkinheritanceclause.swift index 985fc54a30d7a..624a4684226f5 100644 --- a/validation-test/compiler_crashers/28408-swift-typechecker-checkinheritanceclause.swift +++ b/validation-test/compiler_crashers_fixed/28408-swift-typechecker-checkinheritanceclause.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -typecheck +// RUN: not %target-swift-frontend %s -typecheck // REQUIRES: asserts class A{{ { diff --git a/validation-test/compiler_crashers/28423-swift-typechecker-validatedecl.swift b/validation-test/compiler_crashers_fixed/28423-swift-typechecker-validatedecl.swift similarity index 88% rename from validation-test/compiler_crashers/28423-swift-typechecker-validatedecl.swift rename to validation-test/compiler_crashers_fixed/28423-swift-typechecker-validatedecl.swift index d2db33d49c342..0818a1c742db6 100644 --- a/validation-test/compiler_crashers/28423-swift-typechecker-validatedecl.swift +++ b/validation-test/compiler_crashers_fixed/28423-swift-typechecker-validatedecl.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -typecheck +// RUN: not %target-swift-frontend %s -typecheck // REQUIRES: asserts protocol a protocol a{ diff --git a/validation-test/compiler_crashers/28435-swift-genericenvironment-maptypeintocontext.swift b/validation-test/compiler_crashers_fixed/28435-swift-genericenvironment-maptypeintocontext.swift similarity index 88% rename from validation-test/compiler_crashers/28435-swift-genericenvironment-maptypeintocontext.swift rename to validation-test/compiler_crashers_fixed/28435-swift-genericenvironment-maptypeintocontext.swift index cc294ba3d9d45..10118dab66bf0 100644 --- a/validation-test/compiler_crashers/28435-swift-genericenvironment-maptypeintocontext.swift +++ b/validation-test/compiler_crashers_fixed/28435-swift-genericenvironment-maptypeintocontext.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -typecheck +// RUN: not %target-swift-frontend %s -typecheck enum ST:d protocol a{typealias d:A.B{ { diff --git a/validation-test/compiler_crashers/28453-found-interfacetoarchetypemap-end-missing-generic-parameter-failed.swift b/validation-test/compiler_crashers_fixed/28453-found-interfacetoarchetypemap-end-missing-generic-parameter-failed.swift similarity index 89% rename from validation-test/compiler_crashers/28453-found-interfacetoarchetypemap-end-missing-generic-parameter-failed.swift rename to validation-test/compiler_crashers_fixed/28453-found-interfacetoarchetypemap-end-missing-generic-parameter-failed.swift index d56d2ac701ad7..36fc317cecc42 100644 --- a/validation-test/compiler_crashers/28453-found-interfacetoarchetypemap-end-missing-generic-parameter-failed.swift +++ b/validation-test/compiler_crashers_fixed/28453-found-interfacetoarchetypemap-end-missing-generic-parameter-failed.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir // REQUIRES: asserts protocol a{}protocol a{ typealias e=a diff --git a/validation-test/compiler_crashers_fixed/28466-segfault-0xc27624-0xc2741f-0xc25bb5-0xbcdbbb.swift~13e17147798fd3fdc17a53aabf4fe6450eb7c91e b/validation-test/compiler_crashers_fixed/28466-segfault-0xc27624-0xc2741f-0xc25bb5-0xbcdbbb.swift~13e17147798fd3fdc17a53aabf4fe6450eb7c91e new file mode 100644 index 0000000000000..ff2d2222361f6 --- /dev/null +++ b/validation-test/compiler_crashers_fixed/28466-segfault-0xc27624-0xc2741f-0xc25bb5-0xbcdbbb.swift~13e17147798fd3fdc17a53aabf4fe6450eb7c91e @@ -0,0 +1,9 @@ +// This source file is part of the Swift.org open source project +// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + +// RUN: not %target-swift-frontend %s -emit-ir +{associatedtype bfunc c:[T diff --git a/validation-test/compiler_crashers/28471-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift b/validation-test/compiler_crashers_fixed/28471-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift similarity index 88% rename from validation-test/compiler_crashers/28471-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift rename to validation-test/compiler_crashers_fixed/28471-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift index daa3a459981d6..d8ce8eb157165 100644 --- a/validation-test/compiler_crashers/28471-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift +++ b/validation-test/compiler_crashers_fixed/28471-anonymous-namespace-verifier-verifychecked-swift-type-llvm-smallptrset-swift-arc.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir guard{protocol A{ protocol a{}protocol a{typealias d:A{}typealias e class A{ diff --git a/validation-test/compiler_crashers/28545-swift-archetypebuilder-potentialarchetype-gettype-swift-archetypebuilder.swift b/validation-test/compiler_crashers_fixed/28545-swift-archetypebuilder-potentialarchetype-gettype-swift-archetypebuilder.swift similarity index 87% rename from validation-test/compiler_crashers/28545-swift-archetypebuilder-potentialarchetype-gettype-swift-archetypebuilder.swift rename to validation-test/compiler_crashers_fixed/28545-swift-archetypebuilder-potentialarchetype-gettype-swift-archetypebuilder.swift index 3148a608aaa0a..ddf31588d4286 100644 --- a/validation-test/compiler_crashers/28545-swift-archetypebuilder-potentialarchetype-gettype-swift-archetypebuilder.swift +++ b/validation-test/compiler_crashers_fixed/28545-swift-archetypebuilder-potentialarchetype-gettype-swift-archetypebuilder.swift @@ -5,7 +5,7 @@ // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors -// RUN: not --crash %target-swift-frontend %s -emit-ir +// RUN: not %target-swift-frontend %s -emit-ir struct B<>:A protocol A{ typealias d:A.B From 975849935355e0a7128214503a38af2d74f390d2 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 22:36:01 -0800 Subject: [PATCH 10/11] [Type checker] Teach performTypeLocChecking() to provide a generic environment. This routine was passing a 'null' generic environment when it should, in fact, provide the generic environment for its context. Fixes a code-completion regression introduced by the removal of PartialGenericTypeToArchetypeResolver. --- lib/Sema/TypeChecker.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp index f4fa2fffba7df..145529e407062 100644 --- a/lib/Sema/TypeChecker.cpp +++ b/lib/Sema/TypeChecker.cpp @@ -693,11 +693,12 @@ void swift::performWholeModuleTypeChecking(SourceFile &SF) { bool swift::performTypeLocChecking(ASTContext &Ctx, TypeLoc &T, DeclContext *DC, bool ProduceDiagnostics) { - return performTypeLocChecking(Ctx, T, - /*isSILMode=*/false, - /*isSILType=*/false, - /*GenericEnv=*/nullptr, - DC, ProduceDiagnostics); + return performTypeLocChecking( + Ctx, T, + /*isSILMode=*/false, + /*isSILType=*/false, + /*GenericEnv=*/DC->getGenericEnvironmentOfContext(), + DC, ProduceDiagnostics); } bool swift::performTypeLocChecking(ASTContext &Ctx, TypeLoc &T, From 553216a11e48340272aa3a3106e0468a5f58c1ca Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 5 Dec 2016 22:41:27 -0800 Subject: [PATCH 11/11] Address most of Slava's commentary on this PR. --- lib/AST/DeclContext.cpp | 3 +-- lib/Sema/ITCDecl.cpp | 2 +- lib/Sema/TypeCheckConstraints.cpp | 3 +-- lib/Sema/TypeCheckDecl.cpp | 23 ++--------------------- lib/Sema/TypeCheckType.cpp | 9 +++------ 5 files changed, 8 insertions(+), 32 deletions(-) diff --git a/lib/AST/DeclContext.cpp b/lib/AST/DeclContext.cpp index f8526c32714f1..7de508034fbeb 100644 --- a/lib/AST/DeclContext.cpp +++ b/lib/AST/DeclContext.cpp @@ -354,8 +354,7 @@ AbstractFunctionDecl *DeclContext::getInnermostMethodContext() { } bool DeclContext::isTypeContext() const { - return (getContextKind() == DeclContextKind::GenericTypeDecl && - !isa(this)) || + return isa(this) || getContextKind() == DeclContextKind::ExtensionDecl; } diff --git a/lib/Sema/ITCDecl.cpp b/lib/Sema/ITCDecl.cpp index e51bb79a303fd..d7c7e796e8b25 100644 --- a/lib/Sema/ITCDecl.cpp +++ b/lib/Sema/ITCDecl.cpp @@ -103,7 +103,7 @@ void IterativeTypeChecker::processResolveInheritedClauseEntry( // Validate the type of this inherited clause entry. // FIXME: Recursion into existing type checker. - GenericTypeToArchetypeResolver resolver(dc->getGenericEnvironmentOfContext()); + GenericTypeToArchetypeResolver resolver(dc); if (TC.validateType(*inherited, dc, options, &resolver)) { inherited->setInvalidType(getASTContext()); } diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp index 1d797325c82f9..1ff2775c7cf10 100644 --- a/lib/Sema/TypeCheckConstraints.cpp +++ b/lib/Sema/TypeCheckConstraints.cpp @@ -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)); diff --git a/lib/Sema/TypeCheckDecl.cpp b/lib/Sema/TypeCheckDecl.cpp index 8f3f4002d0f0e..d57c64a7dccf7 100644 --- a/lib/Sema/TypeCheckDecl.cpp +++ b/lib/Sema/TypeCheckDecl.cpp @@ -6846,25 +6846,6 @@ void TypeChecker::checkDeclCircularity(NominalTypeDecl *decl) { } } -/// Determine whether the given variable is the implicit 'self' parameter for -/// a function, and return that function if so. -static AbstractFunctionDecl *isImplicitSelfParam(VarDecl *var){ - if (!var->isImplicit()) return nullptr; - - auto param = dyn_cast(var); - if (!param) return nullptr; - - auto func = dyn_cast(var->getDeclContext()); - if (!func) return nullptr; - - if (!func->getDeclContext()->isTypeContext()) return nullptr; - - if (param == func->getImplicitSelfDecl()) - return func; - - return nullptr; -} - void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { if (hasEnabledForbiddenTypecheckPrefix()) checkForForbiddenPrefix(D); @@ -7112,12 +7093,12 @@ void TypeChecker::validateDecl(ValueDecl *D, bool resolveTypeParams) { case DeclKind::Param: { auto VD = cast(D); if (!VD->hasType()) { - if (auto func = isImplicitSelfParam(VD)) { + if (VD->isSelfParameter()) { if (!VD->hasInterfaceType()) { VD->setInterfaceType(ErrorType::get(Context)); VD->setInvalid(); } - recordSelfContextType(func); + recordSelfContextType(cast(VD->getDeclContext())); } else if (PatternBindingDecl *PBD = VD->getParentPatternBinding()) { if (PBD->isBeingTypeChecked()) { diagnose(VD, diag::pattern_used_in_type, VD->getName()); diff --git a/lib/Sema/TypeCheckType.cpp b/lib/Sema/TypeCheckType.cpp index d5e6cf0cc7db8..8f531fa066d5f 100644 --- a/lib/Sema/TypeCheckType.cpp +++ b/lib/Sema/TypeCheckType.cpp @@ -201,8 +201,7 @@ Type TypeChecker::resolveTypeInContext( bool isSpecialized, GenericTypeResolver *resolver, UnsatisfiedDependency *unsatisfiedDependency) { - GenericTypeToArchetypeResolver defaultResolver( - fromDC->getGenericEnvironmentOfContext()); + GenericTypeToArchetypeResolver defaultResolver(fromDC); if (!resolver) resolver = &defaultResolver; @@ -529,8 +528,7 @@ Type TypeChecker::applyUnboundGenericArguments( "invalid arguments, use applyGenericArguments for diagnostic emitting"); // Make sure we always have a resolver to use. - GenericTypeToArchetypeResolver defaultResolver( - dc->getGenericEnvironmentOfContext()); + GenericTypeToArchetypeResolver defaultResolver(dc); if (!resolver) resolver = &defaultResolver; @@ -1613,8 +1611,7 @@ Type TypeChecker::resolveType(TypeRepr *TyR, DeclContext *DC, PrettyStackTraceTypeRepr stackTrace(Context, "resolving", TyR); // Make sure we always have a resolver to use. - GenericTypeToArchetypeResolver defaultResolver( - DC->getGenericEnvironmentOfContext()); + GenericTypeToArchetypeResolver defaultResolver(DC); if (!resolver) resolver = &defaultResolver;