Skip to content

Commit a8c5be0

Browse files
committed
Diagnose invalid module selectors in more places
When a module selector does not start with an identifier, we often end up trying to parse whatever token it *does* have there as something else, which doesn't handle the module selector well. Correct this by speculatively parsing invalid selectors in various places.
1 parent 6a42ae1 commit a8c5be0

File tree

6 files changed

+165
-5
lines changed

6 files changed

+165
-5
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ ERROR(forbidden_extended_escaping_string,none,
9494
ERROR(expected_identifier_in_module_selector,none,
9595
"expected identifier in module selector", ())
9696
ERROR(module_selector_not_allowed,none,
97-
"%select{%error|name in %1 declaration|captured variable name|"
97+
"%select{%error|%error|name in %1 declaration|captured variable name|"
9898
"parameter name|generic parameter name|argument label|SPI group|"
9999
"Objective-C name|name of sibling declaration|precedence group name"
100100
"}0 cannot be qualified with a module selector",

include/swift/Parse/Parser.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1616,11 +1616,16 @@ class Parser {
16161616
void parseOptionalArgumentLabel(Identifier &name, SourceLoc &loc);
16171617

16181618
/// The reason we are trying to parse a module selector. Other than
1619-
/// \c Allowed, all reasons indicate an error should be emitted.
1619+
/// \c Allowed and \c InvalidOnly, all reasons indicate an error should be
1620+
/// emitted.
16201621
enum class ModuleSelectorReason : uint8_t {
16211622
/// Use of a module selector is allowed.
16221623
Allowed,
16231624

1625+
/// Only parse (and diagnose) invalid module selectors here; if the module
1626+
/// selector is valid, return \c None and leave it for later.
1627+
InvalidOnly,
1628+
16241629
/// Not allowed; this is the name of a declaration. The string parameter
16251630
/// describes the declaration in question (e.g. a class, struct, etc.).
16261631
///

lib/Parse/Lexer.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,9 +733,12 @@ static bool isLeftBound(const char *tokBegin, const char *bufferBegin) {
733733
static bool isRightBound(const char *tokEnd, bool isLeftBound,
734734
const char *codeCompletionPtr) {
735735
switch (*tokEnd) {
736+
case ':': // ':' is an expression separator; '::' is not
737+
return tokEnd[1] == ':';
738+
736739
case ' ': case '\r': case '\n': case '\t': // whitespace
737740
case ')': case ']': case '}': // closing delimiters
738-
case ',': case ';': case ':': // expression separators
741+
case ',': case ';': // expression separators
739742
return false;
740743

741744
case '\0':

lib/Parse/ParseExpr.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,9 @@ static Expr *formUnaryArgument(ASTContext &context, Expr *argument) {
520520
/// '&' expr-unary(Mode)
521521
///
522522
ParserResult<Expr> Parser::parseExprUnary(Diag<> Message, bool isExprBasic) {
523+
// If we have an invalid module selector, consume that first.
524+
parseModuleSelector(ModuleSelectorReason::InvalidOnly);
525+
523526
SyntaxParsingContext UnaryContext(SyntaxContext, SyntaxContextKind::Expr);
524527
UnresolvedDeclRefExpr *Operator;
525528
switch (Tok.getKind()) {
@@ -1124,6 +1127,8 @@ Parser::parseExprPostfixSuffix(ParserResult<Expr> Result, bool isExprBasic,
11241127
Tok.setKind(tok::period);
11251128
consumeToken();
11261129

1130+
parseModuleSelector(ModuleSelectorReason::InvalidOnly);
1131+
11271132
// Handle "x.42" - a tuple index.
11281133
if (Tok.is(tok::integer_literal)) {
11291134
DeclNameRef name(Context.getIdentifier(Tok.getText()));
@@ -1552,6 +1557,9 @@ ParserResult<Expr> Parser::parseExprPostfix(Diag<> ID, bool isExprBasic) {
15521557
/// expr-selector
15531558
///
15541559
ParserResult<Expr> Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) {
1560+
// If we have an invalid module selector, consume that first.
1561+
parseModuleSelector(ModuleSelectorReason::InvalidOnly);
1562+
15551563
SyntaxParsingContext ExprContext(SyntaxContext, SyntaxContextKind::Expr);
15561564
switch (Tok.getKind()) {
15571565
case tok::integer_literal: {
@@ -2280,6 +2288,13 @@ parseModuleSelector(ModuleSelectorReason reason, StringRef declKindName) {
22802288
if (peekToken().isNot(tok::colon_colon) && Tok.isNot(tok::colon_colon))
22812289
return None;
22822290

2291+
// Leave these paired tokens to be diagnosed by a future call to
2292+
// `parseModuleSelector()` at the next token, rather than consuming them as
2293+
// malformed module names and causing more errors later in the parser.
2294+
if (Tok.isAny(tok::l_paren, tok::l_brace, tok::l_angle, tok::l_square,
2295+
tok::r_paren, tok::r_brace, tok::r_angle, tok::r_square))
2296+
return None;
2297+
22832298
// We will parse the selector whether or not it's allowed, then early return
22842299
// if it's disallowed, then diagnose any other errors in what we parsed. This
22852300
// will make sure we always consume the module selector's tokens, but don't
@@ -2288,8 +2303,15 @@ parseModuleSelector(ModuleSelectorReason reason, StringRef declKindName) {
22882303

22892304
SourceLoc nameLoc;
22902305
Identifier moduleName;
2291-
if (Tok.is(tok::identifier))
2306+
if (Tok.is(tok::identifier)) {
2307+
// If we are only supposed to consume invalid selectors, leave this for
2308+
// later.
2309+
if (reason == ModuleSelectorReason::InvalidOnly) {
2310+
return None;
2311+
}
2312+
22922313
nameLoc = consumeIdentifier(moduleName, /*diagnoseDollarPrefix=*/true);
2314+
}
22932315
else if (Tok.is(tok::colon_colon))
22942316
// Let nameLoc and colonColonLoc both point to the tok::colon_colon.
22952317
nameLoc = Tok.getLoc();
@@ -2298,7 +2320,8 @@ parseModuleSelector(ModuleSelectorReason reason, StringRef declKindName) {
22982320

22992321
auto colonColonLoc = consumeToken(tok::colon_colon);
23002322

2301-
if (reason != ModuleSelectorReason::Allowed) {
2323+
if (reason != ModuleSelectorReason::Allowed &&
2324+
reason != ModuleSelectorReason::InvalidOnly) {
23022325
diagnose(colonColonLoc, diag::module_selector_not_allowed,
23032326
(uint8_t)reason, declKindName);
23042327

lib/Parse/ParseType.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,9 @@ ParserResult<TypeRepr> Parser::parseSILBoxType(GenericParamList *generics,
332332
///
333333
ParserResult<TypeRepr> Parser::parseType(
334334
Diag<> MessageID, ParseTypeReason reason) {
335+
// If we have an invalid module selector, consume that first.
336+
parseModuleSelector(ModuleSelectorReason::InvalidOnly);
337+
335338
// Start a context for creating type syntax.
336339
SyntaxParsingContext TypeParsingContext(SyntaxContext,
337340
SyntaxContextKind::Type);

test/NameLookup/module_selector.swift

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
// * Cross-import overlays
1212
// * Key paths
1313
// * Key path dynamic member lookup
14+
// * Custom type attributes (and coverage of type attrs generally is sparse)
1415
//
1516
// It also might not cover all combinations of name lookup paths and inputs.
1617

@@ -491,6 +492,131 @@ func badModuleNames() {
491492
// expected-error@-1 {{'NonexistentModule::MyChildType' is not a member type of struct 'ModuleSelectorTestingKit.A'}}
492493
}
493494

495+
struct BadModuleSelectorSyntax { // expected-note {{in declaration of 'BadModuleSelectorSyntax'}}
496+
var a: ::Int
497+
// expected-error@-1 {{expected identifier in module selector}}
498+
499+
var b: (::Int)
500+
// expected-error@-1 {{expected identifier in module selector}}
501+
502+
var c: *::Int
503+
// expected-error@-1 {{expected identifier in module selector}}
504+
505+
var d: _::Int
506+
// expected-error@-1 {{expected identifier in module selector}}
507+
508+
var e: Self::Int
509+
// expected-error@-1 {{expected identifier in module selector}}
510+
511+
var f: self::Int
512+
// expected-error@-1 {{expected identifier in module selector}}
513+
514+
var g: inout::Int
515+
// expected-error@-1 {{expected identifier in module selector}}
516+
517+
var h: Any::Int
518+
// expected-error@-1 {{expected identifier in module selector}}
519+
520+
var aArray: [::Int]
521+
// expected-error@-1 {{expected identifier in module selector}}
522+
523+
var bArray: [(::Int)]
524+
// expected-error@-1 {{expected identifier in module selector}}
525+
526+
var cArray: [*::Int]
527+
// expected-error@-1 {{expected identifier in module selector}}
528+
529+
var dArray: [_::Int]
530+
// expected-error@-1 {{expected identifier in module selector}}
531+
532+
var eArray: [Self::Int]
533+
// expected-error@-1 {{expected identifier in module selector}}
534+
535+
var fArray: [self::Int]
536+
// expected-error@-1 {{expected identifier in module selector}}
537+
538+
var gArray: [inout::Int]
539+
// expected-error@-1 {{expected identifier in module selector}}
540+
541+
var hArray: [Any::Int]
542+
// expected-error@-1 {{expected identifier in module selector}}
543+
544+
var aIndex: String.::Index
545+
// expected-error@-1 {{expected identifier in module selector}}
546+
547+
// FIXME: This gets interpreted as a single `.*` operator; may not be ideal.
548+
var cIndex: String.*::Index
549+
// expected-error@-1 {{consecutive declarations on a line must be separated by ';'}}
550+
// expected-error@-2 {{expected declaration}}
551+
552+
var dIndex: String._::Index
553+
// expected-error@-1 {{expected identifier in module selector}}
554+
555+
var eIndex: String.Self::Index
556+
// expected-error@-1 {{expected identifier in module selector}}
557+
558+
var fIndex: String.self::Index
559+
// expected-error@-1 {{expected identifier in module selector}}
560+
561+
var gIndex: String.inout::Index
562+
// expected-error@-1 {{expected identifier in module selector}}
563+
564+
var hIndex: String.Any::Index
565+
// expected-error@-1 {{expected identifier in module selector}}
566+
567+
func inExpr() {
568+
::print()
569+
// expected-error@-1 {{expected identifier in module selector}}
570+
571+
(::print())
572+
// expected-error@-1 {{expected identifier in module selector}}
573+
574+
*::print()
575+
// expected-error@-1 {{expected identifier in module selector}}
576+
577+
_::print()
578+
// expected-error@-1 {{expected identifier in module selector}}
579+
580+
Self::print()
581+
// expected-error@-1 {{expected identifier in module selector}}
582+
583+
self::print()
584+
// expected-error@-1 {{expected identifier in module selector}}
585+
586+
inout::print()
587+
// expected-error@-1 {{expected identifier in module selector}}
588+
589+
Any::print()
590+
// expected-error@-1 {{expected identifier in module selector}}
591+
592+
_ = 1.::magnitude
593+
// expected-error@-1 {{expected identifier in module selector}}
594+
595+
_ = (1.::magnitude)
596+
// expected-error@-1 {{expected identifier in module selector}}
597+
598+
// FIXME: This gets interpreted as a single `.*` operator; may not be ideal.
599+
_ = 1.*::magnitude
600+
// expected-error@-1 {{expected identifier in module selector}}
601+
// expected-error@-2 {{cannot find operator '.*' in scope}}
602+
603+
_ = 1._::magnitude
604+
// expected-error@-1 {{expected identifier in module selector}}
605+
606+
_ = 1.Self::magnitude
607+
// expected-error@-1 {{expected identifier in module selector}}
608+
609+
_ = 1.self::magnitude
610+
// expected-error@-1 {{expected identifier in module selector}}
611+
612+
_ = 1.inout::magnitude
613+
// expected-error@-1 {{expected identifier in module selector}}
614+
615+
_ = 1.Any::magnitude
616+
// expected-error@-1 {{expected identifier in module selector}}
617+
}
618+
}
619+
494620
@_spi(main::Private)
495621
// expected-error@-1 {{SPI group cannot be qualified with a module selector}} expected-note@-1 {{remove module selector from this name}} {{7-13=}}
496622
public struct BadImplementsAttr: CustomStringConvertible {

0 commit comments

Comments
 (0)