Skip to content

Commit 388f4b8

Browse files
authored
Merge pull request #21370 from DougGregor/shadow-of-the-resultus
[Name lookup] Enable shadowing for type lookup and of the Swift module.
2 parents 73de196 + bbe3aa7 commit 388f4b8

File tree

10 files changed

+205
-113
lines changed

10 files changed

+205
-113
lines changed

include/swift/AST/Type.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,8 @@ namespace llvm {
647647
template<> struct DenseMapInfo<swift::CanType>
648648
: public DenseMapInfo<swift::Type> {
649649
static swift::CanType getEmptyKey() {
650-
return swift::CanType(nullptr);
650+
return swift::CanType(llvm::DenseMapInfo<swift::
651+
TypeBase*>::getEmptyKey());
651652
}
652653
static swift::CanType getTombstoneKey() {
653654
return swift::CanType(llvm::DenseMapInfo<swift::

include/swift/AST/Types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5346,6 +5346,7 @@ inline CanType CanType::getNominalParent() const {
53465346

53475347
inline bool CanType::isActuallyCanonicalOrNull() const {
53485348
return getPointer() == nullptr ||
5349+
getPointer() == llvm::DenseMapInfo<TypeBase *>::getEmptyKey() ||
53495350
getPointer() == llvm::DenseMapInfo<TypeBase *>::getTombstoneKey() ||
53505351
getPointer()->isCanonical();
53515352
}

lib/AST/GenericSignature.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/AST/Types.h"
2525
#include "swift/Basic/STLExtras.h"
2626
#include <functional>
27+
#include "GenericSignatureBuilderImpl.h"
2728

2829
using namespace swift;
2930

@@ -667,11 +668,17 @@ CanType GenericSignature::getCanonicalTypeInContext(Type type,
667668
!isa<DependentMemberType>(component))
668669
return None;
669670

670-
// Find the equivalence class for this dependent member type.
671-
auto equivClass =
672-
builder.resolveEquivalenceClass(
673-
Type(component),
674-
ArchetypeResolutionKind::CompleteWellFormed);
671+
// Find the equivalence class for this dependent type.
672+
auto resolved = builder.maybeResolveEquivalenceClass(
673+
Type(component),
674+
ArchetypeResolutionKind::CompleteWellFormed,
675+
/*wantExactPotentialArchetype=*/false);
676+
if (!resolved) return None;
677+
678+
if (auto concrete = resolved.getAsConcreteType())
679+
return getCanonicalTypeInContext(concrete, builder);
680+
681+
auto equivClass = resolved.getEquivalenceClass(builder);
675682
if (!equivClass) return None;
676683

677684
if (equivClass->concreteType) {

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 1 addition & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "llvm/Support/raw_ostream.h"
4545
#include "llvm/Support/SaveAndRestore.h"
4646
#include <algorithm>
47+
#include "GenericSignatureBuilderImpl.h"
4748

4849
using namespace swift;
4950
using llvm::DenseMap;
@@ -1856,96 +1857,6 @@ void EquivalenceClass::addMember(PotentialArchetype *pa) {
18561857
}
18571858
}
18581859

1859-
class GenericSignatureBuilder::ResolvedType {
1860-
llvm::PointerUnion<PotentialArchetype *, Type> type;
1861-
EquivalenceClass *equivClass;
1862-
1863-
/// For a type that could not be resolved further unless the given
1864-
/// equivalence class changes.
1865-
ResolvedType(EquivalenceClass *equivClass)
1866-
: type(), equivClass(equivClass) { }
1867-
1868-
public:
1869-
/// A specific resolved potential archetype.
1870-
ResolvedType(PotentialArchetype *pa)
1871-
: type(pa), equivClass(pa->getEquivalenceClassIfPresent()) { }
1872-
1873-
/// A resolved type within the given equivalence class.
1874-
ResolvedType(Type type, EquivalenceClass *equivClass)
1875-
: type(type), equivClass(equivClass) {
1876-
assert(type->isTypeParameter() == static_cast<bool>(equivClass) &&
1877-
"type parameters must have equivalence classes");
1878-
}
1879-
1880-
/// Return an unresolved result, which could be resolved when we
1881-
/// learn more information about the given equivalence class.
1882-
static ResolvedType forUnresolved(EquivalenceClass *equivClass) {
1883-
return ResolvedType(equivClass);
1884-
}
1885-
1886-
/// Return a result for a concrete type.
1887-
static ResolvedType forConcrete(Type concreteType) {
1888-
return ResolvedType(concreteType, nullptr);
1889-
}
1890-
1891-
/// Determine whether this result was resolved.
1892-
explicit operator bool() const { return !type.isNull(); }
1893-
1894-
/// Retrieve the dependent type.
1895-
Type getDependentType(GenericSignatureBuilder &builder) const;
1896-
1897-
/// Retrieve the concrete type, or a null type if this result doesn't store
1898-
/// a concrete type.
1899-
Type getAsConcreteType() const {
1900-
assert(*this && "Doesn't contain any result");
1901-
if (equivClass) return Type();
1902-
return type.dyn_cast<Type>();
1903-
}
1904-
1905-
/// Realize a potential archetype for this type parameter.
1906-
PotentialArchetype *realizePotentialArchetype(
1907-
GenericSignatureBuilder &builder);
1908-
1909-
/// Retrieve the potential archetype, if already known.
1910-
PotentialArchetype *getPotentialArchetypeIfKnown() const {
1911-
return type.dyn_cast<PotentialArchetype *>();
1912-
}
1913-
1914-
/// Retrieve the equivalence class into which a resolved type refers.
1915-
EquivalenceClass *getEquivalenceClass(
1916-
GenericSignatureBuilder &builder) const {
1917-
assert(*this && "Only for resolved types");
1918-
if (equivClass) return equivClass;
1919-
1920-
// Create the equivalence class now.
1921-
return type.get<PotentialArchetype *>()
1922-
->getOrCreateEquivalenceClass(builder);
1923-
}
1924-
1925-
/// Retrieve the equivalence class into which a resolved type refers.
1926-
EquivalenceClass *getEquivalenceClassIfPresent() const {
1927-
assert(*this && "Only for resolved types");
1928-
if (equivClass) return equivClass;
1929-
1930-
// Create the equivalence class now.
1931-
return type.get<PotentialArchetype *>()->getEquivalenceClassIfPresent();
1932-
}
1933-
1934-
/// Retrieve the unresolved result.
1935-
EquivalenceClass *getUnresolvedEquivClass() const {
1936-
assert(!*this);
1937-
return equivClass;
1938-
}
1939-
1940-
/// Return an unresolved type.
1941-
///
1942-
/// This loses equivalence-class information that could be useful, which
1943-
/// is unfortunate.
1944-
UnresolvedType getUnresolvedType() const {
1945-
return type;
1946-
}
1947-
};
1948-
19491860
bool EquivalenceClass::recordConformanceConstraint(
19501861
GenericSignatureBuilder &builder,
19511862
ResolvedType type,

lib/AST/GenericSignatureBuilderImpl.h

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//
2+
// GenericSignatureBuilderImpl.h
3+
// Swift
4+
//
5+
// Created by Doug Gregor on 12/17/18.
6+
//
7+
8+
#ifndef SWIFT_AST_GENERIC_SIGNATURE_BUILDER_IMPL_H
9+
#define SWIFT_AST_GENERIC_SIGNATURE_BUILDER_IMPL_H
10+
11+
#include "swift/AST/GenericSignatureBuilder.h"
12+
13+
namespace swift {
14+
15+
class GenericSignatureBuilder::ResolvedType {
16+
llvm::PointerUnion<PotentialArchetype *, Type> type;
17+
EquivalenceClass *equivClass;
18+
19+
/// For a type that could not be resolved further unless the given
20+
/// equivalence class changes.
21+
ResolvedType(EquivalenceClass *equivClass)
22+
: type(), equivClass(equivClass) { }
23+
24+
public:
25+
/// A specific resolved potential archetype.
26+
ResolvedType(PotentialArchetype *pa)
27+
: type(pa), equivClass(pa->getEquivalenceClassIfPresent()) { }
28+
29+
/// A resolved type within the given equivalence class.
30+
ResolvedType(Type type, EquivalenceClass *equivClass)
31+
: type(type), equivClass(equivClass) {
32+
assert(type->isTypeParameter() == static_cast<bool>(equivClass) &&
33+
"type parameters must have equivalence classes");
34+
}
35+
36+
/// Return an unresolved result, which could be resolved when we
37+
/// learn more information about the given equivalence class.
38+
static ResolvedType forUnresolved(EquivalenceClass *equivClass) {
39+
return ResolvedType(equivClass);
40+
}
41+
42+
/// Return a result for a concrete type.
43+
static ResolvedType forConcrete(Type concreteType) {
44+
return ResolvedType(concreteType, nullptr);
45+
}
46+
47+
/// Determine whether this result was resolved.
48+
explicit operator bool() const { return !type.isNull(); }
49+
50+
/// Retrieve the dependent type.
51+
Type getDependentType(GenericSignatureBuilder &builder) const;
52+
53+
/// Retrieve the concrete type, or a null type if this result doesn't store
54+
/// a concrete type.
55+
Type getAsConcreteType() const {
56+
assert(*this && "Doesn't contain any result");
57+
if (equivClass) return Type();
58+
return type.dyn_cast<Type>();
59+
}
60+
61+
/// Realize a potential archetype for this type parameter.
62+
PotentialArchetype *realizePotentialArchetype(
63+
GenericSignatureBuilder &builder);
64+
65+
/// Retrieve the potential archetype, if already known.
66+
PotentialArchetype *getPotentialArchetypeIfKnown() const {
67+
return type.dyn_cast<PotentialArchetype *>();
68+
}
69+
70+
/// Retrieve the equivalence class into which a resolved type refers.
71+
EquivalenceClass *getEquivalenceClass(
72+
GenericSignatureBuilder &builder) const {
73+
assert(*this && "Only for resolved types");
74+
if (equivClass) return equivClass;
75+
76+
// Create the equivalence class now.
77+
return type.get<PotentialArchetype *>()
78+
->getOrCreateEquivalenceClass(builder);
79+
}
80+
81+
/// Retrieve the equivalence class into which a resolved type refers.
82+
EquivalenceClass *getEquivalenceClassIfPresent() const {
83+
assert(*this && "Only for resolved types");
84+
if (equivClass) return equivClass;
85+
86+
// Create the equivalence class now.
87+
return type.get<PotentialArchetype *>()->getEquivalenceClassIfPresent();
88+
}
89+
90+
/// Retrieve the unresolved result.
91+
EquivalenceClass *getUnresolvedEquivClass() const {
92+
assert(!*this);
93+
return equivClass;
94+
}
95+
96+
/// Return an unresolved type.
97+
///
98+
/// This loses equivalence-class information that could be useful, which
99+
/// is unfortunate.
100+
UnresolvedType getUnresolvedType() const {
101+
return type;
102+
}
103+
};
104+
105+
} // end namepsace swift
106+
107+
#endif // SWIFT_AST_GENERIC_SIGNATURE_BUILDER_IMPL_H

lib/AST/NameLookup.cpp

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,24 @@ static void recordShadowedDeclsAfterSignatureMatch(
254254
break;
255255
}
256256

257+
// Prefer declarations in the any module over those in the standard
258+
// library module.
259+
if (auto swiftModule = ctx.getStdlibModule()) {
260+
if ((firstModule == swiftModule) != (secondModule == swiftModule)) {
261+
// If the second module is the standard library module, the second
262+
// declaration is shadowed by the first.
263+
if (secondModule == swiftModule) {
264+
shadowed.insert(secondDecl);
265+
continue;
266+
}
267+
268+
// Otherwise, the first declaration is shadowed by the second. There is
269+
// no point in continuing to compare the first declaration to others.
270+
shadowed.insert(firstDecl);
271+
break;
272+
}
273+
}
274+
257275
// Prefer declarations in an overlay to similar declarations in
258276
// the Clang module it customizes.
259277
if (firstDecl->hasClangNode() != secondDecl->hasClangNode()) {
@@ -336,26 +354,33 @@ static void recordShadowedDecls(ArrayRef<ValueDecl *> decls,
336354
}
337355
}
338356

339-
// We need an interface type here.
340-
if (typeResolver)
341-
typeResolver->resolveDeclSignature(decl);
357+
CanType signature;
342358

343-
// If the decl is currently being validated, this is likely a recursive
344-
// reference and we'll want to skip ahead so as to avoid having its type
345-
// attempt to desugar itself.
346-
if (!decl->hasValidSignature())
347-
continue;
359+
if (!isa<TypeDecl>(decl)) {
360+
// We need an interface type here.
361+
if (typeResolver)
362+
typeResolver->resolveDeclSignature(decl);
348363

349-
// FIXME: the canonical type makes a poor signature, because we don't
350-
// canonicalize away default arguments.
351-
auto signature = decl->getInterfaceType()->getCanonicalType();
364+
// If the decl is currently being validated, this is likely a recursive
365+
// reference and we'll want to skip ahead so as to avoid having its type
366+
// attempt to desugar itself.
367+
if (!decl->hasValidSignature())
368+
continue;
352369

353-
// FIXME: The type of a variable or subscript doesn't include
354-
// enough context to distinguish entities from different
355-
// constrained extensions, so use the overload signature's
356-
// type. This is layering a partial fix upon a total hack.
357-
if (auto asd = dyn_cast<AbstractStorageDecl>(decl))
358-
signature = asd->getOverloadSignatureType();
370+
// FIXME: the canonical type makes a poor signature, because we don't
371+
// canonicalize away default arguments.
372+
signature = decl->getInterfaceType()->getCanonicalType();
373+
374+
// FIXME: The type of a variable or subscript doesn't include
375+
// enough context to distinguish entities from different
376+
// constrained extensions, so use the overload signature's
377+
// type. This is layering a partial fix upon a total hack.
378+
if (auto asd = dyn_cast<AbstractStorageDecl>(decl))
379+
signature = asd->getOverloadSignatureType();
380+
} else if (decl->getDeclContext()->isTypeContext()) {
381+
// Do not apply shadowing rules for member types.
382+
continue;
383+
}
359384

360385
// Record this declaration based on its signature.
361386
auto &known = collisions[signature];
@@ -1169,6 +1194,11 @@ UnqualifiedLookup::UnqualifiedLookup(DeclName Name, DeclContext *DC,
11691194
lookupInModule(&M, {}, Name, CurModuleResults, NLKind::UnqualifiedLookup,
11701195
resolutionKind, TypeResolver, DC, extraImports);
11711196

1197+
// Always perform name shadowing for type lookup.
1198+
if (options.contains(Flags::TypeLookup)) {
1199+
removeShadowedDecls(CurModuleResults, &M);
1200+
}
1201+
11721202
for (auto VD : CurModuleResults)
11731203
Results.push_back(LookupResultEntry(VD));
11741204

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
public enum Result<Value, Error> {
2+
case success(Value)
3+
case failure(Error)
4+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
public class RootClass {
2+
}
3+
4+
public class SubClass: RootClass {
5+
public typealias Member = Int
6+
}
7+
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/MemberTypesInClasses.swift
3+
// RUN: %target-swift-frontend -typecheck %s -I %t -verify
4+
5+
import MemberTypesInClasses
6+
7+
protocol P {
8+
associatedtype Member
9+
}
10+
11+
extension RootClass: P {
12+
typealias Member = SubClass.Member
13+
}
14+
15+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -emit-module -o %t %S/Inputs/HasResult.swift
3+
// RUN: %target-swift-frontend -typecheck %s -I %t -verify
4+
5+
import HasResult
6+
7+
func foo() -> Result<Int, Error> {
8+
return Result<Int, Error>.success(42)
9+
}

0 commit comments

Comments
 (0)