Skip to content

Commit 4170b22

Browse files
committed
Require the name token to immediately follow the type token
1 parent 4776f68 commit 4170b22

4 files changed

+172
-22
lines changed

parser/src/parser.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,11 @@ type type = int
913913
type match = int
914914
type case = int
915915
916+
# soft keyword as value
917+
type foo = type
918+
type foo = match
919+
type foo = case
920+
916921
# multine definitions
917922
type \
918923
X = int
@@ -959,6 +964,8 @@ type (
959964
X = int
960965
)
961966
type = 1
967+
type = x = 1
968+
x = type = 1
962969
"#;
963970
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
964971
}

parser/src/snapshots/rustpython_parser__parser__tests__parse_type_declaration.snap

Lines changed: 84 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

parser/src/snapshots/rustpython_parser__parser__tests__type_as_identifier.snap

Lines changed: 70 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

parser/src/soft_keywords.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,36 +90,37 @@ where
9090
}
9191
// For `type` all of the following conditions must be met:
9292
// 1. The token is at the start of a logical line.
93-
// 2. The type token is followed by a name token.
94-
// 3. The name token is followed by an equality token.
93+
// 2. The type token is immediately followed by a name token.
94+
// 3. The name token is eventually followed by an equality token.
9595
Tok::Type => {
9696
if !self.start_of_line {
9797
next = Some(Ok((soft_to_name(tok), *range)));
9898
} else {
9999
let mut nesting = 0;
100+
let mut first = true;
100101
let mut seen_name = false;
101102
let mut seen_equal = false;
102103
while let Some(Ok((tok, _))) = self.underlying.peek() {
103104
match tok {
104-
Tok::Newline => break,
105-
Tok::Name { .. } if nesting == 0 => seen_name = true,
106-
// We treat a soft keyword token following a type token as a
107-
// name to support cases like `type type = int` or `type match = int`
108-
Tok::Type | Tok::Match | Tok::Case if nesting == 0 => {
109-
seen_name = true
110-
}
105+
Tok::Newline => break,
106+
Tok::Name { .. } |
107+
// We treat a soft keyword token following a type token as a
108+
// name to support cases like `type type = int` or `type match = int`
109+
Tok::Type | Tok::Match | Tok::Case
110+
if first => seen_name = true,
111111
Tok::Equal if nesting == 0 && seen_name => seen_equal = true,
112112
Tok::Lpar | Tok::Lsqb | Tok::Lbrace => nesting += 1,
113113
Tok::Rpar | Tok::Rsqb | Tok::Rbrace => nesting -= 1,
114114
_ => {}
115115
}
116+
first = false;
116117
}
117118
if !(seen_name && seen_equal) {
118119
next = Some(Ok((soft_to_name(tok), *range)));
119120
}
120121
}
121122
}
122-
_ => (), // Not a soft keyword token
123+
_ => (), // Not a soft keyword token
123124
}
124125
}
125126

0 commit comments

Comments
 (0)