Skip to content

Commit bbf03c0

Browse files
committed
[NFC] Sema/TypeCheckType: Refactor for recursive MemberTypeRepr representation
1 parent 6410e58 commit bbf03c0

File tree

5 files changed

+82
-72
lines changed

5 files changed

+82
-72
lines changed

include/swift/AST/TypeRepr.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,10 @@ class DeclRefTypeRepr : public TypeRepr {
363363
DeclNameLoc getNameLoc() const;
364364
DeclNameRef getNameRef() const;
365365

366+
/// Replace the identifier with a new identifier, e.g., due to typo
367+
/// correction.
368+
void overwriteNameRef(DeclNameRef newId);
369+
366370
/// Returns whether this instance has been bound to a type declaration. This
367371
/// happens during type resolution.
368372
bool isBound() const;

lib/AST/TypeRepr.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,11 @@ DeclNameLoc DeclRefTypeRepr::getNameLoc() const {
215215
return const_cast<DeclRefTypeRepr *>(this)->getLastComponent()->getNameLoc();
216216
}
217217

218+
void DeclRefTypeRepr::overwriteNameRef(DeclNameRef newId) {
219+
assert(newId.isSimpleName() && !newId.isSpecial() && !newId.isOperator());
220+
getLastComponent()->overwriteNameRef(newId);
221+
}
222+
218223
bool DeclRefTypeRepr::isBound() const {
219224
return const_cast<DeclRefTypeRepr *>(this)->getLastComponent()->isBound();
220225
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9345,7 +9345,7 @@ bool InvalidTypeSpecializationArity::diagnoseAsError() {
93459345
diagnoseInvalidGenericArguments(getLoc(), D,
93469346
NumArgs, NumParams,
93479347
HasParameterPack,
9348-
/*generic=*/nullptr);
9348+
/*angleBrackets=*/SourceRange());
93499349
return true;
93509350
}
93519351

lib/Sema/TypeCheckType.cpp

Lines changed: 67 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ static unsigned getGenericRequirementKind(TypeResolutionOptions options) {
178178

179179
Type TypeResolution::resolveDependentMemberType(Type baseTy, DeclContext *DC,
180180
SourceRange baseRange,
181-
IdentTypeRepr *repr) const {
181+
MemberTypeRepr *repr) const {
182182
// FIXME(ModQual): Reject qualified names immediately; they cannot be
183183
// dependent member types.
184184
Identifier refIdentifier = repr->getNameRef().getBaseIdentifier();
@@ -675,7 +675,7 @@ void swift::diagnoseInvalidGenericArguments(SourceLoc loc,
675675
unsigned argCount,
676676
unsigned paramCount,
677677
bool hasParameterPack,
678-
GenericIdentTypeRepr *generic) {
678+
SourceRange angleBrackets) {
679679
auto &ctx = decl->getASTContext();
680680
auto &diags = ctx.Diags;
681681

@@ -687,27 +687,27 @@ void swift::diagnoseInvalidGenericArguments(SourceLoc loc,
687687
auto diag = diags
688688
.diagnose(loc, diag::too_few_generic_arguments, decl->getBaseIdentifier(),
689689
argCount, paramCount);
690-
if (generic)
691-
diag.highlight(generic->getAngleBrackets());
690+
if (angleBrackets.isValid())
691+
diag.highlight(angleBrackets);
692692
} else {
693693
auto diag = diags
694694
.diagnose(loc, diag::too_many_generic_arguments, decl->getBaseIdentifier(),
695695
argCount, paramCount);
696-
if (generic)
697-
diag.highlight(generic->getAngleBrackets());
696+
if (angleBrackets.isValid())
697+
diag.highlight(angleBrackets);
698698
}
699699
} else {
700700
if (argCount < paramCount - 1) {
701701
auto diag = diags
702702
.diagnose(loc, diag::too_few_generic_arguments_pack, decl->getBaseIdentifier(),
703703
argCount, paramCount - 1);
704-
if (generic)
705-
diag.highlight(generic->getAngleBrackets());
704+
if (angleBrackets.isValid())
705+
diag.highlight(angleBrackets);
706706
} else {
707707
auto diag = diags
708708
.diagnose(loc, diag::generic_argument_pack_mismatch, decl->getBaseIdentifier());
709-
if (generic)
710-
diag.highlight(generic->getAngleBrackets());
709+
if (angleBrackets.isValid())
710+
diag.highlight(angleBrackets);
711711
}
712712
}
713713

@@ -727,22 +727,20 @@ void swift::diagnoseInvalidGenericArguments(SourceLoc loc,
727727
/// \param type The generic type to which to apply arguments.
728728
/// \param resolution The type resolution to perform.
729729
/// \param silContext Used to look up generic parameters in SIL mode.
730-
/// \param repr The arguments to apply with the angle bracket range for
731-
/// diagnostics.
732-
///
730+
/// \param repr The syntactic representation of \p type, with a possible
731+
/// generic argument list to apply.
733732
/// \returns A BoundGenericType bound to the given arguments, or null on
734733
/// error.
735734
///
736735
/// \see TypeResolution::applyUnboundGenericArguments
737736
static Type applyGenericArguments(Type type, TypeResolution resolution,
738737
SILTypeResolutionContext *silContext,
739-
IdentTypeRepr *repr) {
738+
DeclRefTypeRepr *repr) {
740739
auto options = resolution.getOptions();
741740
auto dc = resolution.getDeclContext();
742741
auto loc = repr->getNameLoc().getBaseNameLoc();
743742

744-
auto *generic = dyn_cast<GenericIdentTypeRepr>(repr);
745-
if (!generic) {
743+
if (!repr->hasGenericArgList()) {
746744
if (auto *const unboundTy = type->getAs<UnboundGenericType>()) {
747745
if (!options.is(TypeResolverContext::TypeAliasDecl) &&
748746
!options.is(TypeResolverContext::ExtensionBinding)) {
@@ -786,14 +784,14 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
786784
}
787785

788786
if (type->hasError()) {
789-
generic->setInvalid();
787+
repr->setInvalid();
790788
return type;
791789
}
792790

793791
auto &ctx = dc->getASTContext();
794792
auto &diags = ctx.Diags;
795793

796-
auto genericArgs = generic->getGenericArgs();
794+
const auto genericArgs = repr->getGenericArgs();
797795

798796
// Parameterized protocol types have their own code path.
799797
if (auto *protoType = type->getAs<ProtocolType>()) {
@@ -803,7 +801,7 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
803801
if (assocTypes.empty()) {
804802
diags.diagnose(loc, diag::protocol_does_not_have_primary_assoc_type,
805803
protoType)
806-
.fixItRemove(generic->getAngleBrackets());
804+
.fixItRemove(repr->getAngleBrackets());
807805
if (!protoDecl->isImplicit()) {
808806
diags.diagnose(protoDecl, diag::decl_declared_here, protoDecl);
809807
}
@@ -862,12 +860,12 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
862860
if (!type->is<ModuleType>()) {
863861
// When turning a SourceRange into CharSourceRange the closing angle
864862
// brackets on nested generics are lexed as one token.
865-
SourceRange angles = generic->getAngleBrackets();
863+
SourceRange angles = repr->getAngleBrackets();
866864
diag.fixItRemoveChars(angles.Start,
867865
angles.End.getAdvancedLocOrInvalid(1));
868866
}
869867

870-
generic->setInvalid();
868+
repr->setInvalid();
871869
}
872870
return ErrorType::get(ctx);
873871
}
@@ -920,7 +918,7 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
920918
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
921919
diagnoseInvalidGenericArguments(
922920
loc, decl, genericArgs.size(), genericParams->size(),
923-
/*hasParameterPack=*/false, generic);
921+
/*hasParameterPack=*/false, repr->getAngleBrackets());
924922
}
925923
return ErrorType::get(ctx);
926924
}
@@ -942,7 +940,7 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
942940
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
943941
diagnoseInvalidGenericArguments(
944942
loc, decl, genericArgs.size(), genericParams->size(),
945-
/*hasParameterPack=*/true, generic);
943+
/*hasParameterPack=*/true, repr->getAngleBrackets());
946944
}
947945
return ErrorType::get(ctx);
948946
}
@@ -987,17 +985,17 @@ static Type applyGenericArguments(Type type, TypeResolution resolution,
987985
if (isPointerToVoid(dc->getASTContext(), result, isMutablePointer)) {
988986
if (isMutablePointer)
989987
diags.diagnose(loc, diag::use_of_void_pointer, "Mutable").
990-
fixItReplace(generic->getSourceRange(), "UnsafeMutableRawPointer");
988+
fixItReplace(repr->getSourceRange(), "UnsafeMutableRawPointer");
991989
else
992990
diags.diagnose(loc, diag::use_of_void_pointer, "").
993-
fixItReplace(generic->getSourceRange(), "UnsafeRawPointer");
991+
fixItReplace(repr->getSourceRange(), "UnsafeRawPointer");
994992
}
995993

996994
if (auto clangDecl = decl->getClangDecl()) {
997995
if (auto classTemplateDecl =
998996
dyn_cast<clang::ClassTemplateDecl>(clangDecl)) {
999997
SmallVector<Type, 2> typesOfGenericArgs;
1000-
for (auto typeRepr : generic->getGenericArgs()) {
998+
for (auto typeRepr : genericArgs) {
1001999
typesOfGenericArgs.push_back(resolution.resolveType(typeRepr));
10021000
}
10031001

@@ -1284,7 +1282,7 @@ static Type resolveTypeDecl(TypeDecl *typeDecl, DeclContext *foundDC,
12841282
// Resolve the type declaration to a specific type. How this occurs
12851283
// depends on the current context and where the type was found.
12861284
Type type = resolution.resolveTypeInContext(typeDecl, foundDC,
1287-
isa<GenericIdentTypeRepr>(repr));
1285+
repr->hasGenericArgList());
12881286

12891287
if (type->hasError() && foundDC &&
12901288
(isa<AssociatedTypeDecl>(typeDecl) || isa<TypeAliasDecl>(typeDecl))) {
@@ -1338,8 +1336,10 @@ static std::string getDeclNameFromContext(DeclContext *dc,
13381336
static Type diagnoseUnknownType(TypeResolution resolution,
13391337
Type parentType,
13401338
SourceRange parentRange,
1341-
IdentTypeRepr *repr,
1339+
DeclRefTypeRepr *repr,
13421340
NameLookupOptions lookupOptions) {
1341+
assert(parentType || isa<IdentTypeRepr>(repr));
1342+
13431343
auto dc = resolution.getDeclContext();
13441344
ASTContext &ctx = dc->getASTContext();
13451345
auto &diags = ctx.Diags;
@@ -1742,7 +1742,7 @@ static Type resolveUnqualifiedIdentTypeRepr(TypeResolution resolution,
17421742

17431743
// We don't allow generic arguments on 'Self'.
17441744
if (selfTypeKind != SelfTypeKind::InvalidSelf &&
1745-
isa<GenericIdentTypeRepr>(repr)) {
1745+
repr->hasGenericArgList()) {
17461746
diagnoseGenericArgumentsOnSelf(resolution, repr, typeDC);
17471747
}
17481748

@@ -1790,13 +1790,12 @@ static void diagnoseAmbiguousMemberType(Type baseTy, SourceRange baseRange,
17901790
/// \param silContext Used to look up generic parameters in SIL mode.
17911791
static Type resolveQualifiedIdentTypeRepr(TypeResolution resolution,
17921792
SILTypeResolutionContext *silContext,
1793-
Type parentTy,
1794-
SourceRange parentRange,
1795-
IdentTypeRepr *repr) {
1793+
Type parentTy, MemberTypeRepr *repr) {
17961794
const auto options = resolution.getOptions();
17971795
auto DC = resolution.getDeclContext();
17981796
auto &ctx = DC->getASTContext();
17991797
auto &diags = ctx.Diags;
1798+
const auto parentRange = repr->getBase()->getSourceRange();
18001799
auto isExtensionBinding = options.is(TypeResolverContext::ExtensionBinding);
18011800

18021801
auto maybeDiagnoseBadMemberType = [&](TypeDecl *member, Type memberType,
@@ -2157,6 +2156,8 @@ namespace {
21572156
SmallVectorImpl<SILYieldInfo> &yields,
21582157
SmallVectorImpl<SILResultInfo> &results,
21592158
llvm::Optional<SILResultInfo> &errorResult);
2159+
NeverNullType resolveDeclRefTypeReprRec(DeclRefTypeRepr *repr,
2160+
TypeResolutionOptions options);
21602161
NeverNullType resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
21612162
TypeResolutionOptions options);
21622163
NeverNullType resolveOwnershipTypeRepr(OwnershipTypeRepr *repr,
@@ -4636,15 +4637,16 @@ bool TypeResolver::resolveSILResults(
46364637
}
46374638

46384639
NeverNullType
4639-
TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
4640-
TypeResolutionOptions options) {
4640+
TypeResolver::resolveDeclRefTypeReprRec(DeclRefTypeRepr *repr,
4641+
TypeResolutionOptions options) {
4642+
auto &ctx = getASTContext();
4643+
46414644
Type result;
46424645

4643-
auto *rootComp = repr->getRoot();
4644-
if (auto *identBase = dyn_cast<IdentTypeRepr>(rootComp)) {
4646+
if (auto *identTR = dyn_cast<IdentTypeRepr>(repr)) {
46454647
// The base component uses unqualified lookup.
46464648
result = resolveUnqualifiedIdentTypeRepr(resolution.withOptions(options),
4647-
silContext, identBase);
4649+
silContext, identTR);
46484650

46494651
if (result && result->isParameterPack() &&
46504652
// Workaround to allow 'shape' type checking of SIL.
@@ -4667,31 +4669,34 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
46674669
}
46684670
}
46694671
} else {
4670-
result = resolveType(rootComp, options);
4671-
}
4672-
4673-
if (result->hasError())
4674-
return ErrorType::get(result->getASTContext());
4672+
auto *qualIdentTR = cast<MemberTypeRepr>(repr);
4673+
auto *baseTR = qualIdentTR->getBase();
46754674

4676-
// Remaining components are resolved via iterated qualified lookups.
4677-
if (auto *memberTR = dyn_cast<MemberTypeRepr>(repr)) {
4678-
SourceRange parentRange = rootComp->getSourceRange();
4679-
for (auto *nestedComp : memberTR->getMemberComponents()) {
4680-
result = resolveQualifiedIdentTypeRepr(resolution.withOptions(options),
4681-
silContext, result, parentRange,
4682-
nestedComp);
4683-
if (result->hasError())
4684-
return ErrorType::get(result->getASTContext());
4675+
Type baseTy;
4676+
if (auto *declRefBaseTR = dyn_cast<DeclRefTypeRepr>(baseTR)) {
4677+
baseTy = resolveDeclRefTypeReprRec(declRefBaseTR, options);
4678+
} else {
4679+
baseTy = resolveType(baseTR, options);
4680+
}
46854681

4686-
parentRange.End = nestedComp->getEndLoc();
4682+
if (baseTy->hasError()) {
4683+
return ErrorType::get(ctx);
46874684
}
4685+
4686+
result = resolveQualifiedIdentTypeRepr(resolution.withOptions(options),
4687+
silContext, baseTy, qualIdentTR);
46884688
}
46894689

4690-
auto lastComp = repr->getLastComponent();
4690+
return result->hasError() ? ErrorType::get(ctx) : result;
4691+
}
4692+
4693+
NeverNullType
4694+
TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
4695+
TypeResolutionOptions options) {
4696+
Type result = resolveDeclRefTypeReprRec(repr, options);
46914697

4692-
// Diagnose an error if the last component's generic arguments are missing.
4693-
if (result->is<UnboundGenericType>() &&
4694-
!isa<GenericIdentTypeRepr>(lastComp) &&
4698+
// Diagnose an error if generic arguments are missing.
4699+
if (result->is<UnboundGenericType>() && !repr->hasGenericArgList() &&
46954700
!resolution.getUnboundTypeOpener() &&
46964701
!options.is(TypeResolverContext::TypeAliasDecl) &&
46974702
!options.is(TypeResolverContext::ExtensionBinding)) {
@@ -4700,14 +4705,13 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
47004705
// Tailored diagnostic for custom attributes.
47014706
if (options.is(TypeResolverContext::CustomAttr)) {
47024707
auto &ctx = resolution.getASTContext();
4703-
ctx.Diags.diagnose(lastComp->getNameLoc(), diag::unknown_attribute,
4704-
lastComp->getNameRef().getBaseIdentifier().str());
4708+
ctx.Diags.diagnose(repr->getNameLoc(), diag::unknown_attribute,
4709+
repr->getNameRef().getBaseIdentifier().str());
47054710

47064711
return ErrorType::get(ctx);
47074712
}
47084713

4709-
diagnoseUnboundGenericType(result,
4710-
lastComp->getNameLoc().getBaseNameLoc());
4714+
diagnoseUnboundGenericType(result, repr->getNameLoc().getBaseNameLoc());
47114715
}
47124716

47134717
return ErrorType::get(result->getASTContext());
@@ -4720,11 +4724,11 @@ TypeResolver::resolveDeclRefTypeRepr(DeclRefTypeRepr *repr,
47204724
// Otherwise, emit an error.
47214725
if (!options.contains(TypeResolutionFlags::SilenceErrors)) {
47224726
auto moduleName = moduleTy->getModule()->getName();
4723-
diagnose(lastComp->getNameLoc(), diag::cannot_find_type_in_scope,
4727+
diagnose(repr->getNameLoc(), diag::cannot_find_type_in_scope,
47244728
DeclNameRef(moduleName));
4725-
diagnose(lastComp->getNameLoc(), diag::note_module_as_type, moduleName);
4729+
diagnose(repr->getNameLoc(), diag::note_module_as_type, moduleName);
47264730
}
4727-
lastComp->setInvalid();
4731+
repr->setInvalid();
47284732
return ErrorType::get(getASTContext());
47294733
}
47304734

lib/Sema/TypeCheckType.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ namespace swift {
2626

2727
class ASTContext;
2828
class TypeRepr;
29-
class IdentTypeRepr;
29+
class MemberTypeRepr;
3030
class PackElementTypeRepr;
3131
class GenericEnvironment;
3232
class GenericSignature;
3333
class SILTypeResolutionContext;
34-
class GenericIdentTypeRepr;
3534

3635
/// Flags that describe the context of type checking a pattern or
3736
/// type.
@@ -625,7 +624,7 @@ class TypeResolution {
625624
/// name.
626625
Type resolveDependentMemberType(Type baseTy, DeclContext *DC,
627626
SourceRange baseRange,
628-
IdentTypeRepr *repr) const;
627+
MemberTypeRepr *repr) const;
629628

630629
/// Determine whether the given two types are equivalent within this
631630
/// type resolution context.
@@ -667,12 +666,10 @@ class TypeResolution {
667666
ArrayRef<Type> genericArgs) const;
668667
};
669668

670-
void diagnoseInvalidGenericArguments(SourceLoc loc,
671-
ValueDecl *decl,
672-
unsigned argCount,
673-
unsigned paramCount,
669+
void diagnoseInvalidGenericArguments(SourceLoc loc, ValueDecl *decl,
670+
unsigned argCount, unsigned paramCount,
674671
bool hasParameterPack,
675-
GenericIdentTypeRepr *generic);
672+
SourceRange angleBrackets);
676673

677674
/// \param repr the repr for the type of the parameter.
678675
/// \param ty the non-error resolved type of the repr.

0 commit comments

Comments
 (0)