Skip to content

Commit 2f8998a

Browse files
authored
Merge pull request #62288 from slavapestov/various-fixes
A couple of random name lookup fixes
2 parents af742ad + c11a424 commit 2f8998a

File tree

11 files changed

+77
-79
lines changed

11 files changed

+77
-79
lines changed

include/swift/AST/Decl.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3565,10 +3565,6 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
35653565
/// Prepare to traverse the list of extensions.
35663566
void prepareExtensions();
35673567

3568-
/// Add loaded members from all extensions. Eagerly load any members that we
3569-
/// can't lazily load.
3570-
void addLoadedExtensions();
3571-
35723568
/// Retrieve the conformance loader (if any), and removing it in the
35733569
/// same operation. The caller is responsible for loading the
35743570
/// conformances.
@@ -3583,13 +3579,19 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
35833579
std::pair<LazyMemberLoader *, uint64_t> takeConformanceLoaderSlow();
35843580

35853581
/// A lookup table containing all of the members of this type and
3586-
/// its extensions.
3582+
/// its extensions, together with a bit indicating if the table
3583+
/// has been prepared.
35873584
///
35883585
/// The table itself is lazily constructed and updated when
35893586
/// lookupDirect() is called.
3590-
MemberLookupTable *LookupTable = nullptr;
3587+
llvm::PointerIntPair<MemberLookupTable *, 1, bool> LookupTable;
3588+
3589+
/// Get the lookup table, lazily constructing an empty table if
3590+
/// necessary.
3591+
MemberLookupTable *getLookupTable();
35913592

35923593
/// Prepare the lookup table to make it ready for lookups.
3594+
/// Does nothing when called more than once.
35933595
void prepareLookupTable();
35943596

35953597
/// Note that we have added a member into the iterable declaration context,

lib/AST/ASTContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,9 +3023,12 @@ TypeAliasType::TypeAliasType(TypeAliasDecl *typealias, Type parent,
30233023

30243024
// Record the substitutions.
30253025
if (substitutions) {
3026+
assert(typealias->getGenericSignature()->isEqual(
3027+
substitutions.getGenericSignature()));
30263028
Bits.TypeAliasType.HasSubstitutionMap = true;
30273029
*getTrailingObjects<SubstitutionMap>() = substitutions;
30283030
} else {
3031+
assert(!typealias->isGenericContext());
30293032
Bits.TypeAliasType.HasSubstitutionMap = false;
30303033
}
30313034
}

lib/AST/NameLookup.cpp

Lines changed: 45 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,10 +1192,6 @@ void LazyConformanceLoader::anchor() {}
11921192
/// Lookup table used to store members of a nominal type (and its extensions)
11931193
/// for fast retrieval.
11941194
class swift::MemberLookupTable : public ASTAllocated<swift::MemberLookupTable> {
1195-
/// The last extension that was included within the member lookup table's
1196-
/// results.
1197-
ExtensionDecl *LastExtensionIncluded = nullptr;
1198-
11991195
/// The type of the internal lookup table.
12001196
typedef llvm::DenseMap<DeclName, llvm::TinyPtrVector<ValueDecl *>>
12011197
LookupTable;
@@ -1212,9 +1208,6 @@ class swift::MemberLookupTable : public ASTAllocated<swift::MemberLookupTable> {
12121208
/// Create a new member lookup table.
12131209
explicit MemberLookupTable(ASTContext &ctx);
12141210

1215-
/// Update a lookup table with members from newly-added extensions.
1216-
void updateLookupTable(NominalTypeDecl *nominal);
1217-
12181211
/// Add the given member to the lookup table.
12191212
void addMember(Decl *members);
12201213

@@ -1250,12 +1243,6 @@ class swift::MemberLookupTable : public ASTAllocated<swift::MemberLookupTable> {
12501243
}
12511244

12521245
void dump(llvm::raw_ostream &os) const {
1253-
os << "LastExtensionIncluded:\n";
1254-
if (LastExtensionIncluded)
1255-
LastExtensionIncluded->printContext(os, 2);
1256-
else
1257-
os << " nullptr\n";
1258-
12591246
os << "Lookup:\n ";
12601247
for (auto &pair : Lookup) {
12611248
pair.getFirst().print(os);
@@ -1357,42 +1344,32 @@ void MemberLookupTable::addMembers(DeclRange members) {
13571344
}
13581345
}
13591346

1360-
void MemberLookupTable::updateLookupTable(NominalTypeDecl *nominal) {
1361-
// If the last extension we included is the same as the last known extension,
1362-
// we're already up-to-date.
1363-
if (LastExtensionIncluded == nominal->LastExtension)
1347+
void NominalTypeDecl::addedExtension(ExtensionDecl *ext) {
1348+
if (!LookupTable.getInt())
13641349
return;
13651350

1366-
// Add members from each of the extensions that we have not yet visited.
1367-
for (auto next = LastExtensionIncluded
1368-
? LastExtensionIncluded->NextExtension.getPointer()
1369-
: nominal->FirstExtension;
1370-
next;
1371-
(LastExtensionIncluded = next,next = next->NextExtension.getPointer())) {
1372-
addMembers(next->getMembers());
1373-
}
1374-
}
1375-
1376-
void NominalTypeDecl::addedExtension(ExtensionDecl *ext) {
1377-
if (!LookupTable) return;
1351+
auto *table = LookupTable.getPointer();
1352+
assert(table);
13781353

13791354
if (ext->hasLazyMembers()) {
1380-
LookupTable->addMembers(ext->getCurrentMembersWithoutLoading());
1381-
LookupTable->clearLazilyCompleteCache();
1355+
table->addMembers(ext->getCurrentMembersWithoutLoading());
1356+
table->clearLazilyCompleteCache();
13821357
} else {
1383-
LookupTable->addMembers(ext->getMembers());
1358+
table->addMembers(ext->getMembers());
13841359
}
13851360
}
13861361

13871362
void NominalTypeDecl::addedMember(Decl *member) {
13881363
// If we have a lookup table, add the new member to it. If not, we'll pick up
13891364
// this member when we first create the table.
13901365
auto *vd = dyn_cast<ValueDecl>(member);
1391-
auto *lookup = LookupTable;
1392-
if (!vd || !lookup)
1366+
if (!vd || !LookupTable.getInt())
13931367
return;
13941368

1395-
lookup->addMember(vd);
1369+
auto *table = LookupTable.getPointer();
1370+
assert(table);
1371+
1372+
table->addMember(vd);
13961373
}
13971374

13981375
void ExtensionDecl::addedMember(Decl *member) {
@@ -1406,9 +1383,7 @@ void ExtensionDecl::addedMember(Decl *member) {
14061383
}
14071384

14081385
void NominalTypeDecl::addMemberToLookupTable(Decl *member) {
1409-
prepareLookupTable();
1410-
1411-
LookupTable->addMember(member);
1386+
getLookupTable()->addMember(member);
14121387
}
14131388

14141389
// For lack of anywhere more sensible to put it, here's a diagram of the pieces
@@ -1506,37 +1481,52 @@ populateLookupTableEntryFromExtensions(ASTContext &ctx,
15061481
}
15071482
}
15081483

1484+
MemberLookupTable *NominalTypeDecl::getLookupTable() {
1485+
if (!LookupTable.getPointer()) {
1486+
auto &ctx = getASTContext();
1487+
LookupTable.setPointer(new (ctx) MemberLookupTable(ctx));
1488+
}
1489+
1490+
return LookupTable.getPointer();
1491+
}
1492+
15091493
void NominalTypeDecl::prepareLookupTable() {
1510-
// If we have already allocated the lookup table, then there's nothing further
1494+
// If we have already prepared the lookup table, then there's nothing further
15111495
// to do.
1512-
if (LookupTable) {
1496+
if (LookupTable.getInt())
15131497
return;
1514-
}
15151498

1516-
// Otherwise start the first fill.
1517-
auto &ctx = getASTContext();
1518-
LookupTable = new (ctx) MemberLookupTable(ctx);
1499+
auto *table = getLookupTable();
15191500

1501+
// Otherwise start the first fill.
15201502
if (hasLazyMembers()) {
15211503
assert(!hasUnparsedMembers());
1522-
LookupTable->addMembers(getCurrentMembersWithoutLoading());
1504+
table->addMembers(getCurrentMembersWithoutLoading());
15231505
} else {
1524-
LookupTable->addMembers(getMembers());
1506+
table->addMembers(getMembers());
15251507
}
1526-
}
15271508

1528-
void NominalTypeDecl::addLoadedExtensions() {
1509+
// Note: this calls prepareExtensions()
15291510
for (auto e : getExtensions()) {
15301511
// If we can lazy-load this extension, only take the members we've loaded
15311512
// so far.
1513+
//
1514+
// FIXME: This should be 'e->hasLazyMembers()' but that crashes` because
1515+
// some imported extensions don't have a Clang node, and only support
1516+
// LazyMemberLoader::loadAllMembers() and not
1517+
// LazyMemberLoader::loadNamedMembers().
15321518
if (e->wasDeserialized() || e->hasClangNode()) {
1533-
LookupTable->addMembers(e->getCurrentMembersWithoutLoading());
1519+
table->addMembers(e->getCurrentMembersWithoutLoading());
15341520
continue;
15351521
}
15361522

15371523
// Else, load all the members into the table.
1538-
LookupTable->addMembers(e->getMembers());
1524+
table->addMembers(e->getMembers());
15391525
}
1526+
1527+
// Any extensions added after this point will add their members to the
1528+
// lookup table.
1529+
LookupTable.setInt(true);
15401530
}
15411531

15421532
static TinyPtrVector<ValueDecl *>
@@ -1592,12 +1582,12 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
15921582

15931583
decl->prepareLookupTable();
15941584

1595-
// If we're allowed to load extensions, call addLoadedExtensions to ensure we
1596-
// properly invalidate the lazily-complete cache for any extensions brought in
1597-
// by modules loaded after-the-fact. This can happen with the LLDB REPL.
1598-
decl->addLoadedExtensions();
1585+
// Call prepareExtensions() to ensure we properly invalidate the
1586+
// lazily-complete cache for any extensions brought in by modules
1587+
// loaded after-the-fact. This can happen with the LLDB REPL.
1588+
decl->prepareExtensions();
15991589

1600-
auto &Table = *decl->LookupTable;
1590+
auto &Table = *decl->getLookupTable();
16011591
if (!useNamedLazyMemberLoading) {
16021592
// Make sure we have the complete list of members (in this nominal and in
16031593
// all extensions).
@@ -1606,7 +1596,6 @@ DirectLookupRequest::evaluate(Evaluator &evaluator,
16061596
for (auto E : decl->getExtensions())
16071597
(void)E->getMembers();
16081598

1609-
Table.updateLookupTable(decl);
16101599
} else if (!Table.isLazilyComplete(name.getBaseName())) {
16111600
DeclBaseName baseName(name.getBaseName());
16121601

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ StructuralRequirementsRequest::evaluate(Evaluator &evaluator,
831831
}
832832

833833
/// This request primarily emits diagnostics about typealiases and associated
834-
/// type declarations that override another associate type, and can better be
834+
/// type declarations that override another associated type, and can better be
835835
/// expressed as requirements in the 'where' clause.
836836
///
837837
/// It also implements a compatibility behavior where sometimes typealiases in

lib/IDE/CompletionLookup.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1684,14 +1684,10 @@ void CompletionLookup::addTypeAliasRef(const TypeAliasDecl *TAD,
16841684
Builder.addBaseName(TAD->getName().str());
16851685
if (auto underlyingType = TAD->getUnderlyingType()) {
16861686
if (underlyingType->hasError()) {
1687-
Type parentType;
1688-
if (auto nominal = TAD->getDeclContext()->getSelfNominalTypeDecl()) {
1689-
parentType = nominal->getDeclaredInterfaceType();
1690-
}
16911687
addTypeAnnotation(Builder,
1692-
TypeAliasType::get(const_cast<TypeAliasDecl *>(TAD),
1693-
parentType, SubstitutionMap(),
1694-
underlyingType));
1688+
TAD->isGeneric()
1689+
? TAD->getUnboundGenericType()
1690+
: TAD->getDeclaredInterfaceType());
16951691

16961692
} else {
16971693
addTypeAnnotation(Builder, underlyingType);

lib/Sema/ImportResolution.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,8 +1060,7 @@ ScopedImportLookupRequest::evaluate(Evaluator &evaluator,
10601060
emittedDiag.emplace(ctx.Diags.diagnose(
10611061
importLoc, diag::imported_decl_is_wrong_kind_typealias,
10621062
typealias->getDescriptiveKind(),
1063-
TypeAliasType::get(typealias, Type(), SubstitutionMap(),
1064-
typealias->getUnderlyingType()),
1063+
typealias->getDeclaredInterfaceType(),
10651064
getImportKindString(importKind)));
10661065
} else {
10671066
emittedDiag.emplace(ctx.Diags.diagnose(

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3376,8 +3376,6 @@ void ConformanceChecker::recordTypeWitness(AssociatedTypeDecl *assocType,
33763376

33773377
aliasDecl->setImplicit();
33783378
aliasDecl->setSynthesized();
3379-
if (type->hasError())
3380-
aliasDecl->setInvalid();
33813379

33823380
// Inject the typealias into the nominal decl that conforms to the protocol.
33833381
if (auto nominal = DC->getSelfNominalTypeDecl()) {

lib/Sema/TypeCheckType.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4623,7 +4623,7 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
46234623

46244624
auto *aliasDecl = dyn_cast<TypeAliasDecl>(member);
46254625
if (aliasDecl) {
4626-
if (aliasDecl->getGenericParams()) {
4626+
if (aliasDecl->isGeneric()) {
46274627
return UnboundGenericType::get(
46284628
aliasDecl, baseTy,
46294629
aliasDecl->getASTContext());
@@ -4647,7 +4647,7 @@ Type TypeChecker::substMemberTypeWithBase(ModuleDecl *module,
46474647
if (baseTy->is<ErrorType>())
46484648
return ErrorType::get(memberType);
46494649

4650-
subs = baseTy->getContextSubstitutionMap(module, member->getDeclContext());
4650+
subs = baseTy->getMemberSubstitutionMap(module, member);
46514651
resultType = memberType.subst(subs);
46524652
} else {
46534653
resultType = memberType;

test/Generics/where_clause_contextually_generic_decls.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ struct Container<T> {
127127
// expected-error@-1 {{invalid redeclaration of 'NestedAlias}}
128128
typealias NestedAlias2 = T.Magnitude where T: FixedWidthInteger
129129

130+
typealias NestedAlias3 = T.Element where T: Sequence
131+
130132
class NestedClass where T: Equatable {}
131133
}
132134

@@ -154,3 +156,12 @@ _ = Container<Bool>.NestedClass.self
154156
_ = Container<String>.NestedStruct.self
155157
_ = Container<Array<UInt8>>.NestedStruct2.self
156158
_ = Container<Array<Double>>.NestedStruct2.NestedEnum.self
159+
160+
// Make sure the substitution here actually succeeds instead of producing an ErrorType
161+
func sameType<T>(_: T.Type, _: T.Type) {}
162+
sameType(Container<Array<Int>>.NestedAlias3.self, Int.self)
163+
sameType(Container<Array<Bool>>.NestedAlias3.self, Int.self)
164+
// expected-error@-1 {{cannot convert value of type 'Int.Type' to expected argument type 'Container<Array<Bool>>.NestedAlias3.Type' (aka 'Bool.Type')}}
165+
166+
sameType(Container<Array<Int>>.NestedAlias3.self, Bool.self)
167+
// expected-error@-1 {{cannot convert value of type 'Bool.Type' to expected argument type 'Container<Array<Int>>.NestedAlias3.Type' (aka 'Int.Type')}}

test/ImportResolution/import-specific-fixits.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import struct DeclsUsedWrongly.Choice // expected-error {{'Choice' was imported
3636
import struct DeclsUsedWrongly.Callback // expected-error {{type alias 'Callback' (aka '() -> ()') cannot be imported as 'struct'}} {{8-14=typealias}}
3737
import var DeclsUsedWrongly.Callback // expected-error {{'Callback' was imported as 'var', but is a type}} {{8-11=typealias}}
3838

39-
import struct DeclsUsedWrongly.Pair // expected-error {{type alias 'Pair' (aka '(T, T)') cannot be imported as 'struct'}} {{8-14=typealias}}
39+
import struct DeclsUsedWrongly.Pair // expected-error {{type alias 'Pair<T>' (aka '(T, T)') cannot be imported as 'struct'}} {{8-14=typealias}}
4040
import var DeclsUsedWrongly.Pair // expected-error {{'Pair' was imported as 'var', but is a type}} {{8-11=typealias}}
4141

4242
import struct Swift.print // expected-error {{'print' was imported as 'struct', but is a function}} {{8-14=func}}

0 commit comments

Comments
 (0)