Skip to content

Commit 3939650

Browse files
authored
Merge pull request #34556 from beccadax/mod-squad-2
[SE-0491] Implement lookup and diagnostics for module selectors (MyMod::someName)
2 parents 405a267 + e6d8b02 commit 3939650

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1396
-198
lines changed

include/swift/AST/ASTBridging.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,13 @@ BridgedDeclNameRef_createParsed(BridgedASTContext cContext,
164164

165165
class BridgedDeclNameLoc {
166166
const void *_Nullable LocationInfo;
167-
size_t NumArgumentLabels;
167+
uint32_t NumArgumentLabels;
168+
bool HasModuleSelectorLoc;
168169

169170
public:
170-
BridgedDeclNameLoc() : LocationInfo(nullptr), NumArgumentLabels(0) {}
171+
BridgedDeclNameLoc()
172+
: LocationInfo(nullptr), NumArgumentLabels(0), HasModuleSelectorLoc(false)
173+
{}
171174

172175
BRIDGED_INLINE BridgedDeclNameLoc(swift::DeclNameLoc loc);
173176

include/swift/AST/ASTBridgingImpl.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,12 @@ swift::DeclNameRef BridgedDeclNameRef::unbridged() const {
6060

6161
BridgedDeclNameLoc::BridgedDeclNameLoc(swift::DeclNameLoc loc)
6262
: LocationInfo(loc.LocationInfo),
63-
NumArgumentLabels(loc.NumArgumentLabels) {}
63+
NumArgumentLabels(loc.NumArgumentLabels),
64+
HasModuleSelectorLoc(loc.HasModuleSelectorLoc) {}
6465

6566
swift::DeclNameLoc BridgedDeclNameLoc::unbridged() const {
66-
return swift::DeclNameLoc(LocationInfo, NumArgumentLabels);
67+
return swift::DeclNameLoc(LocationInfo, NumArgumentLabels,
68+
HasModuleSelectorLoc);
6769
}
6870

6971
//===----------------------------------------------------------------------===//

include/swift/AST/Decl.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3071,11 +3071,10 @@ class ValueDecl : public Decl {
30713071
return Name.getBaseIdentifier();
30723072
}
30733073

3074-
/// Generates a DeclNameRef referring to this declaration with as much
3075-
/// specificity as possible.
3076-
DeclNameRef createNameRef() const {
3077-
return DeclNameRef(Name);
3078-
}
3074+
/// Generates a DeclNameRef referring to this declaration.
3075+
///
3076+
/// \param moduleSelector If true, the name ref includes the module name.
3077+
DeclNameRef createNameRef(bool moduleSelector = false) const;
30793078

30803079
/// Retrieve the C declaration name that names this function, or empty
30813080
/// string if it has none.

include/swift/AST/DeclNameLoc.h

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,61 +35,69 @@ class DeclNameLoc {
3535

3636
/// Source location information.
3737
///
38-
/// If \c NumArgumentLabels == 0, this is the SourceLoc for the base name.
39-
/// Otherwise, it points to an array of SourceLocs, which contains:
38+
/// If \c NumArgumentLabels == 0 and \c !HasModuleSelectorLoc, this is the
39+
/// SourceLoc for the base name. Otherwise, it points to an array of
40+
/// SourceLocs, which contains:
4041
/// * The base name location
42+
/// * The module selector location
4143
/// * The left parentheses location
4244
/// * The right parentheses location
4345
/// * The locations of each of the argument labels.
4446
const void *LocationInfo;
4547

4648
/// The number of argument labels stored in the name.
47-
unsigned NumArgumentLabels;
49+
uint32_t NumArgumentLabels;
50+
bool HasModuleSelectorLoc;
4851

4952
enum {
5053
BaseNameIndex = 0,
51-
LParenIndex = 1,
52-
RParenIndex = 2,
53-
FirstArgumentLabelIndex = 3,
54+
ModuleSelectorIndex = 1,
55+
LParenIndex = 2,
56+
RParenIndex = 3,
57+
FirstArgumentLabelIndex = 4,
5458
};
5559

5660
/// Retrieve a pointer to either the only source location that was
5761
/// stored or to the array of source locations that was stored.
5862
SourceLoc const * getSourceLocs() const {
59-
if (NumArgumentLabels == 0)
63+
if (NumArgumentLabels == 0 && !HasModuleSelectorLoc)
6064
return reinterpret_cast<SourceLoc const *>(&LocationInfo);
6165

6266
return reinterpret_cast<SourceLoc const *>(LocationInfo);
6367
}
6468

65-
DeclNameLoc(const void *LocationInfo, unsigned NumArgumentLabels)
66-
: LocationInfo(LocationInfo), NumArgumentLabels(NumArgumentLabels) {}
69+
DeclNameLoc(const void *LocationInfo, unsigned NumArgumentLabels,
70+
bool HasModuleSelectorLoc)
71+
: LocationInfo(LocationInfo), NumArgumentLabels(NumArgumentLabels),
72+
HasModuleSelectorLoc(HasModuleSelectorLoc) {}
6773

6874
public:
6975
/// Create an invalid declaration name location.
70-
DeclNameLoc() : DeclNameLoc(nullptr, 0) {}
76+
DeclNameLoc() : DeclNameLoc(nullptr, 0, false) {}
7177

7278
/// Create declaration name location information for a base name.
7379
explicit DeclNameLoc(SourceLoc baseNameLoc)
74-
: DeclNameLoc(baseNameLoc.getOpaquePointerValue(), 0) {}
80+
: DeclNameLoc(baseNameLoc.getOpaquePointerValue(), 0, false) {}
7581

7682
explicit DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc,
7783
SourceLoc baseNameLoc)
78-
: DeclNameLoc(baseNameLoc) { }
84+
: DeclNameLoc(ctx, moduleSelectorLoc, baseNameLoc,
85+
SourceLoc(), {}, SourceLoc()) { }
7986

8087
/// Create declaration name location information for a compound
8188
/// name.
8289
DeclNameLoc(ASTContext &ctx, SourceLoc baseNameLoc,
8390
SourceLoc lParenLoc,
8491
ArrayRef<SourceLoc> argumentLabelLocs,
85-
SourceLoc rParenLoc);
92+
SourceLoc rParenLoc)
93+
: DeclNameLoc(ctx, SourceLoc(), baseNameLoc,
94+
lParenLoc, argumentLabelLocs, rParenLoc) { }
8695

8796
DeclNameLoc(ASTContext &ctx, SourceLoc moduleSelectorLoc,
8897
SourceLoc baseNameLoc,
8998
SourceLoc lParenLoc,
9099
ArrayRef<SourceLoc> argumentLabelLocs,
91-
SourceLoc rParenLoc)
92-
: DeclNameLoc(ctx, baseNameLoc, lParenLoc, argumentLabelLocs, rParenLoc) { }
100+
SourceLoc rParenLoc);
93101

94102
/// Whether the location information is valid.
95103
bool isValid() const { return getBaseNameLoc().isValid(); }
@@ -125,11 +133,12 @@ class DeclNameLoc {
125133
}
126134

127135
SourceLoc getModuleSelectorLoc() const {
128-
return SourceLoc();
136+
if (!HasModuleSelectorLoc) return SourceLoc();
137+
return getSourceLocs()[ModuleSelectorIndex];
129138
}
130139

131140
SourceLoc getStartLoc() const {
132-
return getBaseNameLoc();
141+
return HasModuleSelectorLoc ? getModuleSelectorLoc() : getBaseNameLoc();
133142
}
134143

135144
SourceLoc getEndLoc() const {
@@ -138,9 +147,7 @@ class DeclNameLoc {
138147

139148
/// Retrieve the complete source range for this declaration name.
140149
SourceRange getSourceRange() const {
141-
if (NumArgumentLabels == 0) return getBaseNameLoc();
142-
143-
return SourceRange(getBaseNameLoc(), getRParenLoc());
150+
return SourceRange(getStartLoc(), getEndLoc());
144151
}
145152
};
146153

include/swift/AST/DiagnosticsSema.def

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1146,6 +1146,10 @@ ERROR(no_module_type,none,
11461146
"no type named %0 in module %1", (DeclNameRef, Identifier))
11471147
ERROR(ambiguous_module_type,none,
11481148
"ambiguous type name %0 in module %1", (DeclNameRef, Identifier))
1149+
ERROR(module_selector_dependent_member_type_not_allowed,none,
1150+
"module selector is not allowed on generic member type; associated types "
1151+
"with the same name are merged instead of shadowing one another",
1152+
())
11491153
ERROR(use_nonmatching_operator,none,
11501154
"%0 is not a %select{binary|prefix unary|postfix unary}1 operator",
11511155
(DeclNameRef, unsigned))
@@ -1191,6 +1195,16 @@ ERROR(cannot_find_type_in_cast_expression,none,
11911195
"type-casting operator expects a type on its right-hand side (got: %kind0)", (const ValueDecl *))
11921196
ERROR(cannot_find_type_in_scope_did_you_mean,none,
11931197
"cannot find type %0 in scope; did you mean to use '%1'?", (DeclNameRef, StringRef))
1198+
ERROR(wrong_module_selector,none,
1199+
"%0 is not imported through module %1", (DeclName, Identifier))
1200+
NOTE(note_change_module_selector,none,
1201+
"did you mean module %0?", (Identifier))
1202+
NOTE(note_remove_module_selector_local_decl,none,
1203+
"did you mean the local declaration?", ())
1204+
NOTE(note_remove_module_selector_outer_type,none,
1205+
"did you mean an outer type member?", ())
1206+
NOTE(note_add_explicit_self_with_module_selector,none,
1207+
"did you mean the member of 'self'?", ())
11941208
NOTE(note_typo_candidate_implicit_member,none,
11951209
"did you mean the implicitly-synthesized %kindbase0?", (const ValueDecl *))
11961210
NOTE(note_remapped_type,none,
@@ -8013,7 +8027,7 @@ ERROR(expected_macro_expansion_expr,PointsToFirstBadToken,
80138027
ERROR(expected_macro_expansion_decls,PointsToFirstBadToken,
80148028
"expected macro expansion to produce a declaration", ())
80158029
ERROR(macro_undefined,PointsToFirstBadToken,
8016-
"no macro named %0", (DeclName))
8030+
"no macro named %0", (DeclNameRef))
80178031
ERROR(external_macro_not_found,none,
80188032
"external macro implementation type '%0.%1' could not be found for "
80198033
"macro %2; %3", (StringRef, StringRef, DeclName, StringRef))

include/swift/AST/Identifier.h

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -738,39 +738,76 @@ void simple_display(llvm::raw_ostream &out, DeclName name);
738738
/// An in-source reference to another declaration, including qualification
739739
/// information.
740740
class DeclNameRef {
741-
DeclName FullName;
741+
friend class ASTContext;
742+
friend struct llvm::PointerLikeTypeTraits<DeclNameRef>;
743+
744+
/// Contains the name and module for a DeclNameRef with a module selector.
745+
struct alignas(Identifier) SelectiveDeclNameRef : llvm::FoldingSetNode {
746+
Identifier moduleSelector; // Note: currently can never be empty().
747+
DeclName fullName;
748+
749+
SelectiveDeclNameRef(Identifier moduleSelector, DeclName fullName)
750+
: moduleSelector(moduleSelector), fullName(fullName) { }
751+
752+
/// Uniquing for the ASTContext.
753+
static void Profile(llvm::FoldingSetNodeID &id, Identifier moduleSelector,
754+
DeclName fullName);
755+
756+
void Profile(llvm::FoldingSetNodeID &id) {
757+
Profile(id, moduleSelector, fullName);
758+
}
759+
};
760+
761+
using Storage = llvm::PointerUnion<DeclName, SelectiveDeclNameRef *>;
762+
Storage storage;
763+
764+
explicit DeclNameRef(void *_Nullable Opaque)
765+
: storage(decltype(storage)::getFromOpaqueValue(Opaque)) { }
766+
767+
void initialize(ASTContext &C, Identifier moduleScope, DeclName fullName);
742768

743769
public:
744770
static DeclNameRef createSubscript();
745771
static DeclNameRef createConstructor();
772+
static DeclNameRef createSelf(const ASTContext &ctx);
746773

747-
DeclNameRef() : FullName() { }
774+
DeclNameRef() : storage(DeclName()) { }
748775

749-
void *_Nullable getOpaqueValue() const { return FullName.getOpaqueValue(); }
776+
void *_Nullable getOpaqueValue() const {
777+
return storage.getOpaqueValue();
778+
}
750779
static DeclNameRef getFromOpaqueValue(void *_Nullable p);
751780

752781
explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
753-
DeclName fullName)
754-
: FullName(fullName) { }
782+
DeclName fullName) {
783+
initialize(C, moduleSelector, fullName);
784+
}
755785

756786
explicit DeclNameRef(ASTContext &C, Identifier moduleSelector,
757-
DeclBaseName baseName, ArrayRef<Identifier> argLabels)
758-
: FullName(C, baseName, argLabels) { }
787+
DeclBaseName baseName, ArrayRef<Identifier> argLabels) {
788+
initialize(C, moduleSelector, DeclName(C, baseName, argLabels));
789+
}
759790

760791
explicit DeclNameRef(DeclName FullName)
761-
: FullName(FullName) { }
792+
: storage(FullName) { }
762793

763794
bool hasModuleSelector() const {
764-
return false;
795+
return isa<SelectiveDeclNameRef *>(storage);
765796
}
766797

767798
Identifier getModuleSelector() const {
768-
return Identifier();
799+
if (!hasModuleSelector())
800+
return Identifier();
801+
802+
return cast<SelectiveDeclNameRef *>(storage)->moduleSelector;
769803
}
770804

771805
/// The name of the declaration being referenced.
772806
DeclName getFullName() const {
773-
return FullName;
807+
if (!hasModuleSelector())
808+
return cast<DeclName>(storage);
809+
810+
return cast<SelectiveDeclNameRef *>(storage)->fullName;
774811
}
775812

776813
/// The base name of the declaration being referenced.
@@ -885,7 +922,7 @@ class DeclNameRef {
885922
};
886923

887924
inline DeclNameRef DeclNameRef::getFromOpaqueValue(void *_Nullable p) {
888-
return DeclNameRef(DeclName::getFromOpaqueValue(p));
925+
return DeclNameRef(p);
889926
}
890927

891928
inline DeclNameRef DeclNameRef::withoutArgumentLabels(ASTContext &C) const {
@@ -1059,7 +1096,6 @@ namespace llvm {
10591096
};
10601097

10611098
// A DeclNameRef is "pointer like" just like DeclNames.
1062-
template<typename T> struct PointerLikeTypeTraits;
10631099
template<>
10641100
struct PointerLikeTypeTraits<swift::DeclNameRef> {
10651101
public:
@@ -1069,7 +1105,7 @@ namespace llvm {
10691105
static inline swift::DeclNameRef getFromVoidPointer(void *_Nullable ptr) {
10701106
return swift::DeclNameRef::getFromOpaqueValue(ptr);
10711107
}
1072-
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclName>::NumLowBitsAvailable };
1108+
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::DeclNameRef::Storage>::NumLowBitsAvailable };
10731109
};
10741110

10751111
// DeclNameRefs hash just like DeclNames.

include/swift/AST/LookupKinds.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ enum class ModuleLookupFlags : unsigned {
104104
/// If @abi attributes are present, return the decls representing the ABI,
105105
/// not the API.
106106
ABIProviding = 1 << 1,
107+
/// The lookup is qualified by a module selector which has specified this
108+
/// module explicitly.
109+
HasModuleSelector = 1 << 2,
107110
};
108111

109112
} // end namespace swift

include/swift/AST/Module.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,11 @@ class ModuleDecl
481481
void getDeclaredCrossImportBystanders(
482482
SmallVectorImpl<Identifier> &bystanderNames);
483483

484+
/// Returns the name that should be used for this module in a module
485+
/// selector. For separately-imported overlays, this will be the declaring
486+
/// module's name.
487+
Identifier getNameForModuleSelector();
488+
484489
/// Retrieve the ABI name of the module, which is used for metadata and
485490
/// mangling.
486491
Identifier getABIName() const;

include/swift/AST/ModuleNameLookup.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,35 @@ enum class ResolutionKind {
4444

4545
void simple_display(llvm::raw_ostream &out, ResolutionKind kind);
4646

47-
/// Performs a lookup into the given module and it's imports.
47+
/// Performs a lookup into the given module and its imports.
4848
///
49-
/// If 'moduleOrFile' is a ModuleDecl, we search the module and it's
49+
/// If 'moduleOrFile' is a ModuleDecl, we search the module and its
5050
/// public imports. If 'moduleOrFile' is a SourceFile, we search the
5151
/// file's parent module, the module's public imports, and the source
5252
/// file's private imports.
5353
///
54-
/// \param moduleOrFile The module or file unit whose imports to search.
54+
/// \param moduleOrFile The module or file unit to search, including imports.
5555
/// \param name The name to look up.
56+
/// \param hasModuleSelector Whether \p name was originally qualified by a
57+
/// module selector. This information is threaded through to underlying
58+
/// lookup calls; the callee is responsible for actually applying the
59+
/// module selector.
5660
/// \param[out] decls Any found decls will be added to this vector.
5761
/// \param lookupKind Whether this lookup is qualified or unqualified.
5862
/// \param resolutionKind What sort of decl is expected.
5963
/// \param moduleScopeContext The top-level context from which the lookup is
6064
/// being performed, for checking access. This must be either a
6165
/// FileUnit or a Module.
66+
/// \param loc Source location of the lookup. Used to add contextual options,
67+
/// such as disabling macro expansions inside macro arguments.
6268
/// \param options name lookup options. Currently only used to communicate the
63-
/// NL_IncludeUsableFromInline option.
69+
/// NL_IncludeUsableFromInline option.
6470
void lookupInModule(const DeclContext *moduleOrFile,
65-
DeclName name, SmallVectorImpl<ValueDecl *> &decls,
66-
NLKind lookupKind, ResolutionKind resolutionKind,
71+
DeclName name,
72+
bool hasModuleSelector,
73+
SmallVectorImpl<ValueDecl *> &decls,
74+
NLKind lookupKind,
75+
ResolutionKind resolutionKind,
6776
const DeclContext *moduleScopeContext,
6877
SourceLoc loc, NLOptions options);
6978

0 commit comments

Comments
 (0)