Skip to content

Commit 23307c1

Browse files
committed
Require the name token to immediately follow the type token
1 parent 1d2cec2 commit 23307c1

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
@@ -886,6 +886,11 @@ type type = int
886886
type match = int
887887
type case = int
888888
889+
# soft keyword as value
890+
type foo = type
891+
type foo = match
892+
type foo = case
893+
889894
# multine definitions
890895
type \
891896
X = int
@@ -932,6 +937,8 @@ type (
932937
X = int
933938
)
934939
type = 1
940+
type = x = 1
941+
x = type = 1
935942
"#;
936943
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
937944
}

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)