mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:35 +00:00
[syntax-errors] Irrefutable case pattern before final case (#16905)
Summary -- Detects irrefutable `match` cases before the final case using a modified version of the existing `Pattern::is_irrefutable` method from the AST crate. The modified method helps to retrieve a more precise diagnostic range to match what Python 3.13 shows in the REPL. Test Plan -- New inline tests, as well as some updates to existing tests that had irrefutable patterns before the last block.
This commit is contained in:
parent
58350ec93b
commit
5697d21fca
17 changed files with 1420 additions and 594 deletions
|
@ -549,12 +549,14 @@ impl SemanticSyntaxContext for Checker<'_> {
|
||||||
}
|
}
|
||||||
SemanticSyntaxErrorKind::ReboundComprehensionVariable
|
SemanticSyntaxErrorKind::ReboundComprehensionVariable
|
||||||
| SemanticSyntaxErrorKind::DuplicateTypeParameter
|
| SemanticSyntaxErrorKind::DuplicateTypeParameter
|
||||||
|
| SemanticSyntaxErrorKind::IrrefutableCasePattern(_)
|
||||||
if self.settings.preview.is_enabled() =>
|
if self.settings.preview.is_enabled() =>
|
||||||
{
|
{
|
||||||
self.semantic_errors.borrow_mut().push(error);
|
self.semantic_errors.borrow_mut().push(error);
|
||||||
}
|
}
|
||||||
SemanticSyntaxErrorKind::ReboundComprehensionVariable
|
SemanticSyntaxErrorKind::ReboundComprehensionVariable
|
||||||
| SemanticSyntaxErrorKind::DuplicateTypeParameter => {}
|
| SemanticSyntaxErrorKind::DuplicateTypeParameter
|
||||||
|
| SemanticSyntaxErrorKind::IrrefutableCasePattern(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2244,12 +2244,33 @@ impl Pattern {
|
||||||
///
|
///
|
||||||
/// [irrefutable pattern]: https://peps.python.org/pep-0634/#irrefutable-case-blocks
|
/// [irrefutable pattern]: https://peps.python.org/pep-0634/#irrefutable-case-blocks
|
||||||
pub fn is_irrefutable(&self) -> bool {
|
pub fn is_irrefutable(&self) -> bool {
|
||||||
match self {
|
self.irrefutable_pattern().is_some()
|
||||||
Pattern::MatchAs(PatternMatchAs { pattern: None, .. }) => true,
|
|
||||||
Pattern::MatchOr(PatternMatchOr { patterns, .. }) => {
|
|
||||||
patterns.iter().any(Pattern::is_irrefutable)
|
|
||||||
}
|
}
|
||||||
_ => false,
|
|
||||||
|
/// Return `Some(IrrefutablePattern)` if `self` is irrefutable or `None` otherwise.
|
||||||
|
pub fn irrefutable_pattern(&self) -> Option<IrrefutablePattern> {
|
||||||
|
match self {
|
||||||
|
Pattern::MatchAs(PatternMatchAs {
|
||||||
|
pattern,
|
||||||
|
name,
|
||||||
|
range,
|
||||||
|
}) => match pattern {
|
||||||
|
Some(pattern) => pattern.irrefutable_pattern(),
|
||||||
|
None => match name {
|
||||||
|
Some(name) => Some(IrrefutablePattern {
|
||||||
|
kind: IrrefutablePatternKind::Name(name.id.clone()),
|
||||||
|
range: *range,
|
||||||
|
}),
|
||||||
|
None => Some(IrrefutablePattern {
|
||||||
|
kind: IrrefutablePatternKind::Wildcard,
|
||||||
|
range: *range,
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Pattern::MatchOr(PatternMatchOr { patterns, .. }) => {
|
||||||
|
patterns.iter().find_map(Pattern::irrefutable_pattern)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2277,6 +2298,17 @@ impl Pattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct IrrefutablePattern {
|
||||||
|
pub kind: IrrefutablePatternKind,
|
||||||
|
pub range: TextRange,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum IrrefutablePatternKind {
|
||||||
|
Name(Name),
|
||||||
|
Wildcard,
|
||||||
|
}
|
||||||
|
|
||||||
/// See also [MatchValue](https://docs.python.org/3/library/ast.html#ast.MatchValue)
|
/// See also [MatchValue](https://docs.python.org/3/library/ast.html#ast.MatchValue)
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct PatternMatchValue {
|
pub struct PatternMatchValue {
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
match x:
|
||||||
|
case var: ... # capture pattern
|
||||||
|
case 2: ...
|
||||||
|
match x:
|
||||||
|
case _: ...
|
||||||
|
case 2: ... # wildcard pattern
|
||||||
|
match x:
|
||||||
|
case var1 as var2: ... # as pattern with irrefutable left-hand side
|
||||||
|
case 2: ...
|
||||||
|
match x:
|
||||||
|
case enum.variant | var: ... # or pattern with irrefutable part
|
||||||
|
case 2: ...
|
|
@ -0,0 +1,9 @@
|
||||||
|
match x:
|
||||||
|
case 2: ...
|
||||||
|
case var: ...
|
||||||
|
match x:
|
||||||
|
case 2: ...
|
||||||
|
case _: ...
|
||||||
|
match x:
|
||||||
|
case var if True: ... # don't try to refute a guarded pattern
|
||||||
|
case 2: ...
|
|
@ -1,3 +1,4 @@
|
||||||
match foo:
|
match foo:
|
||||||
case foo_bar: ...
|
case foo_bar: ...
|
||||||
|
match foo:
|
||||||
case _: ...
|
case _: ...
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
match foo:
|
match foo:
|
||||||
case case: ...
|
case case: ...
|
||||||
|
match foo:
|
||||||
case match: ...
|
case match: ...
|
||||||
|
match foo:
|
||||||
case type: ...
|
case type: ...
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
match subject:
|
match subject:
|
||||||
case a: ...
|
|
||||||
case a if x: ...
|
case a if x: ...
|
||||||
case a, b: ...
|
case a, b: ...
|
||||||
case a, b if x: ...
|
case a, b if x: ...
|
||||||
|
case a: ...
|
||||||
|
|
|
@ -243,18 +243,21 @@ match x:
|
||||||
match x:
|
match x:
|
||||||
case a:
|
case a:
|
||||||
...
|
...
|
||||||
|
match x:
|
||||||
case a as b:
|
case a as b:
|
||||||
...
|
...
|
||||||
|
match x:
|
||||||
case 1 | 2 as two:
|
case 1 | 2 as two:
|
||||||
...
|
...
|
||||||
case 1 + 3j as sum:
|
case 1 + 3j as sum:
|
||||||
...
|
...
|
||||||
case a.b as ab:
|
case a.b as ab:
|
||||||
...
|
...
|
||||||
case _:
|
|
||||||
...
|
|
||||||
case _ as x:
|
case _ as x:
|
||||||
...
|
...
|
||||||
|
match x:
|
||||||
|
case _:
|
||||||
|
...
|
||||||
|
|
||||||
# PatternMatchSequence
|
# PatternMatchSequence
|
||||||
match x:
|
match x:
|
||||||
|
|
|
@ -1060,10 +1060,10 @@ impl RecoveryContextKind {
|
||||||
None => {
|
None => {
|
||||||
// test_ok match_sequence_pattern_terminator
|
// test_ok match_sequence_pattern_terminator
|
||||||
// match subject:
|
// match subject:
|
||||||
// case a: ...
|
|
||||||
// case a if x: ...
|
// case a if x: ...
|
||||||
// case a, b: ...
|
// case a, b: ...
|
||||||
// case a, b if x: ...
|
// case a, b if x: ...
|
||||||
|
// case a: ...
|
||||||
matches!(p.current_token_kind(), TokenKind::Colon | TokenKind::If)
|
matches!(p.current_token_kind(), TokenKind::Colon | TokenKind::If)
|
||||||
.then_some(ListTerminatorKind::Regular)
|
.then_some(ListTerminatorKind::Regular)
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,13 +488,16 @@ impl Parser<'_> {
|
||||||
// test_ok match_as_pattern_soft_keyword
|
// test_ok match_as_pattern_soft_keyword
|
||||||
// match foo:
|
// match foo:
|
||||||
// case case: ...
|
// case case: ...
|
||||||
|
// match foo:
|
||||||
// case match: ...
|
// case match: ...
|
||||||
|
// match foo:
|
||||||
// case type: ...
|
// case type: ...
|
||||||
let ident = self.parse_identifier();
|
let ident = self.parse_identifier();
|
||||||
|
|
||||||
// test_ok match_as_pattern
|
// test_ok match_as_pattern
|
||||||
// match foo:
|
// match foo:
|
||||||
// case foo_bar: ...
|
// case foo_bar: ...
|
||||||
|
// match foo:
|
||||||
// case _: ...
|
// case _: ...
|
||||||
Pattern::MatchAs(ast::PatternMatchAs {
|
Pattern::MatchAs(ast::PatternMatchAs {
|
||||||
range: ident.range,
|
range: ident.range,
|
||||||
|
|
|
@ -9,7 +9,7 @@ use std::fmt::Display;
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
self as ast,
|
self as ast,
|
||||||
visitor::{walk_expr, Visitor},
|
visitor::{walk_expr, Visitor},
|
||||||
Expr, PythonVersion, Stmt, StmtExpr, StmtImportFrom,
|
Expr, IrrefutablePatternKind, PythonVersion, Stmt, StmtExpr, StmtImportFrom,
|
||||||
};
|
};
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
||||||
|
@ -54,27 +54,30 @@ impl SemanticSyntaxChecker {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_stmt<Ctx: SemanticSyntaxContext>(&mut self, stmt: &ast::Stmt, ctx: &Ctx) {
|
fn check_stmt<Ctx: SemanticSyntaxContext>(&mut self, stmt: &ast::Stmt, ctx: &Ctx) {
|
||||||
if let Stmt::ImportFrom(StmtImportFrom { range, module, .. }) = stmt {
|
match stmt {
|
||||||
|
Stmt::ImportFrom(StmtImportFrom { range, module, .. }) => {
|
||||||
if self.seen_futures_boundary && matches!(module.as_deref(), Some("__future__")) {
|
if self.seen_futures_boundary && matches!(module.as_deref(), Some("__future__")) {
|
||||||
Self::add_error(ctx, SemanticSyntaxErrorKind::LateFutureImport, *range);
|
Self::add_error(ctx, SemanticSyntaxErrorKind::LateFutureImport, *range);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Stmt::Match(match_stmt) => {
|
||||||
Self::duplicate_type_parameter_name(stmt, ctx);
|
Self::irrefutable_match_case(match_stmt, ctx);
|
||||||
|
}
|
||||||
|
Stmt::FunctionDef(ast::StmtFunctionDef { type_params, .. })
|
||||||
|
| Stmt::ClassDef(ast::StmtClassDef { type_params, .. })
|
||||||
|
| Stmt::TypeAlias(ast::StmtTypeAlias { type_params, .. }) => {
|
||||||
|
if let Some(type_params) = type_params {
|
||||||
|
Self::duplicate_type_parameter_name(type_params, ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn duplicate_type_parameter_name<Ctx: SemanticSyntaxContext>(stmt: &ast::Stmt, ctx: &Ctx) {
|
fn duplicate_type_parameter_name<Ctx: SemanticSyntaxContext>(
|
||||||
let (Stmt::FunctionDef(ast::StmtFunctionDef { type_params, .. })
|
type_params: &ast::TypeParams,
|
||||||
| Stmt::ClassDef(ast::StmtClassDef { type_params, .. })
|
ctx: &Ctx,
|
||||||
| Stmt::TypeAlias(ast::StmtTypeAlias { type_params, .. })) = stmt
|
) {
|
||||||
else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(type_params) = type_params else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
if type_params.len() < 2 {
|
if type_params.len() < 2 {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +112,49 @@ impl SemanticSyntaxChecker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn irrefutable_match_case<Ctx: SemanticSyntaxContext>(stmt: &ast::StmtMatch, ctx: &Ctx) {
|
||||||
|
// test_ok irrefutable_case_pattern_at_end
|
||||||
|
// match x:
|
||||||
|
// case 2: ...
|
||||||
|
// case var: ...
|
||||||
|
// match x:
|
||||||
|
// case 2: ...
|
||||||
|
// case _: ...
|
||||||
|
// match x:
|
||||||
|
// case var if True: ... # don't try to refute a guarded pattern
|
||||||
|
// case 2: ...
|
||||||
|
|
||||||
|
// test_err irrefutable_case_pattern
|
||||||
|
// match x:
|
||||||
|
// case var: ... # capture pattern
|
||||||
|
// case 2: ...
|
||||||
|
// match x:
|
||||||
|
// case _: ...
|
||||||
|
// case 2: ... # wildcard pattern
|
||||||
|
// match x:
|
||||||
|
// case var1 as var2: ... # as pattern with irrefutable left-hand side
|
||||||
|
// case 2: ...
|
||||||
|
// match x:
|
||||||
|
// case enum.variant | var: ... # or pattern with irrefutable part
|
||||||
|
// case 2: ...
|
||||||
|
for case in stmt
|
||||||
|
.cases
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.skip(1)
|
||||||
|
.filter_map(|case| match case.guard {
|
||||||
|
Some(_) => None,
|
||||||
|
None => case.pattern.irrefutable_pattern(),
|
||||||
|
})
|
||||||
|
{
|
||||||
|
Self::add_error(
|
||||||
|
ctx,
|
||||||
|
SemanticSyntaxErrorKind::IrrefutableCasePattern(case.kind),
|
||||||
|
case.range,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn visit_stmt<Ctx: SemanticSyntaxContext>(&mut self, stmt: &ast::Stmt, ctx: &Ctx) {
|
pub fn visit_stmt<Ctx: SemanticSyntaxContext>(&mut self, stmt: &ast::Stmt, ctx: &Ctx) {
|
||||||
// update internal state
|
// update internal state
|
||||||
match stmt {
|
match stmt {
|
||||||
|
@ -209,7 +255,7 @@ pub struct SemanticSyntaxError {
|
||||||
|
|
||||||
impl Display for SemanticSyntaxError {
|
impl Display for SemanticSyntaxError {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self.kind {
|
match &self.kind {
|
||||||
SemanticSyntaxErrorKind::LateFutureImport => {
|
SemanticSyntaxErrorKind::LateFutureImport => {
|
||||||
f.write_str("__future__ imports must be at the top of the file")
|
f.write_str("__future__ imports must be at the top of the file")
|
||||||
}
|
}
|
||||||
|
@ -219,11 +265,23 @@ impl Display for SemanticSyntaxError {
|
||||||
SemanticSyntaxErrorKind::DuplicateTypeParameter => {
|
SemanticSyntaxErrorKind::DuplicateTypeParameter => {
|
||||||
f.write_str("duplicate type parameter")
|
f.write_str("duplicate type parameter")
|
||||||
}
|
}
|
||||||
|
SemanticSyntaxErrorKind::IrrefutableCasePattern(kind) => match kind {
|
||||||
|
// These error messages are taken from CPython's syntax errors
|
||||||
|
IrrefutablePatternKind::Name(name) => {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"name capture `{name}` makes remaining patterns unreachable"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
IrrefutablePatternKind::Wildcard => {
|
||||||
|
f.write_str("wildcard makes remaining patterns unreachable")
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum SemanticSyntaxErrorKind {
|
pub enum SemanticSyntaxErrorKind {
|
||||||
/// Represents the use of a `__future__` import after the beginning of a file.
|
/// Represents the use of a `__future__` import after the beginning of a file.
|
||||||
///
|
///
|
||||||
|
@ -265,6 +323,26 @@ pub enum SemanticSyntaxErrorKind {
|
||||||
/// class C[T, T]: ...
|
/// class C[T, T]: ...
|
||||||
/// ```
|
/// ```
|
||||||
DuplicateTypeParameter,
|
DuplicateTypeParameter,
|
||||||
|
|
||||||
|
/// Represents an irrefutable `case` pattern before the last `case` in a `match` statement.
|
||||||
|
///
|
||||||
|
/// According to the [Python reference], "a match statement may have at most one irrefutable
|
||||||
|
/// case block, and it must be last."
|
||||||
|
///
|
||||||
|
/// ## Examples
|
||||||
|
///
|
||||||
|
/// ```python
|
||||||
|
/// match x:
|
||||||
|
/// case value: ... # irrefutable capture pattern
|
||||||
|
/// case other: ...
|
||||||
|
///
|
||||||
|
/// match x:
|
||||||
|
/// case _: ... # irrefutable wildcard pattern
|
||||||
|
/// case other: ...
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// [Python reference]: https://docs.python.org/3/reference/compound_stmts.html#irrefutable-case-blocks
|
||||||
|
IrrefutableCasePattern(IrrefutablePatternKind),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Searches for the first named expression (`x := y`) rebinding one of the `iteration_variables` in
|
/// Searches for the first named expression (`x := y`) rebinding one of the `iteration_variables` in
|
||||||
|
|
|
@ -0,0 +1,374 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/err/irrefutable_case_pattern.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..317,
|
||||||
|
body: [
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 0..61,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 6..7,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
|
MatchCase {
|
||||||
|
range: 13..26,
|
||||||
|
pattern: MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 18..21,
|
||||||
|
pattern: None,
|
||||||
|
name: Some(
|
||||||
|
Identifier {
|
||||||
|
id: Name("var"),
|
||||||
|
range: 18..21,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 23..26,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 23..26,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 50..61,
|
||||||
|
pattern: MatchValue(
|
||||||
|
PatternMatchValue {
|
||||||
|
range: 55..56,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 55..56,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 58..61,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 58..61,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 62..102,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 68..69,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
|
MatchCase {
|
||||||
|
range: 75..86,
|
||||||
|
pattern: MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 80..81,
|
||||||
|
pattern: None,
|
||||||
|
name: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 83..86,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 83..86,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 91..102,
|
||||||
|
pattern: MatchValue(
|
||||||
|
PatternMatchValue {
|
||||||
|
range: 96..97,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 96..97,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 99..102,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 99..102,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 125..222,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 131..132,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
|
MatchCase {
|
||||||
|
range: 138..160,
|
||||||
|
pattern: MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 143..155,
|
||||||
|
pattern: Some(
|
||||||
|
MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 143..147,
|
||||||
|
pattern: None,
|
||||||
|
name: Some(
|
||||||
|
Identifier {
|
||||||
|
id: Name("var1"),
|
||||||
|
range: 143..147,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
name: Some(
|
||||||
|
Identifier {
|
||||||
|
id: Name("var2"),
|
||||||
|
range: 151..155,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 157..160,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 157..160,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 211..222,
|
||||||
|
pattern: MatchValue(
|
||||||
|
PatternMatchValue {
|
||||||
|
range: 216..217,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 216..217,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 219..222,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 219..222,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 223..316,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 229..230,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
|
MatchCase {
|
||||||
|
range: 236..264,
|
||||||
|
pattern: MatchOr(
|
||||||
|
PatternMatchOr {
|
||||||
|
range: 241..259,
|
||||||
|
patterns: [
|
||||||
|
MatchValue(
|
||||||
|
PatternMatchValue {
|
||||||
|
range: 241..253,
|
||||||
|
value: Attribute(
|
||||||
|
ExprAttribute {
|
||||||
|
range: 241..253,
|
||||||
|
value: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 241..245,
|
||||||
|
id: Name("enum"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
attr: Identifier {
|
||||||
|
id: Name("variant"),
|
||||||
|
range: 246..253,
|
||||||
|
},
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 256..259,
|
||||||
|
pattern: None,
|
||||||
|
name: Some(
|
||||||
|
Identifier {
|
||||||
|
id: Name("var"),
|
||||||
|
range: 256..259,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 261..264,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 261..264,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 305..316,
|
||||||
|
pattern: MatchValue(
|
||||||
|
PatternMatchValue {
|
||||||
|
range: 310..311,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 310..311,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 313..316,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 313..316,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
||||||
|
## Semantic Syntax Errors
|
||||||
|
|
||||||
|
|
|
||||||
|
1 | match x:
|
||||||
|
2 | case var: ... # capture pattern
|
||||||
|
| ^^^ Syntax Error: name capture `var` makes remaining patterns unreachable
|
||||||
|
3 | case 2: ...
|
||||||
|
4 | match x:
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
3 | case 2: ...
|
||||||
|
4 | match x:
|
||||||
|
5 | case _: ...
|
||||||
|
| ^ Syntax Error: wildcard makes remaining patterns unreachable
|
||||||
|
6 | case 2: ... # wildcard pattern
|
||||||
|
7 | match x:
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
6 | case 2: ... # wildcard pattern
|
||||||
|
7 | match x:
|
||||||
|
8 | case var1 as var2: ... # as pattern with irrefutable left-hand side
|
||||||
|
| ^^^^ Syntax Error: name capture `var1` makes remaining patterns unreachable
|
||||||
|
9 | case 2: ...
|
||||||
|
10 | match x:
|
||||||
|
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
9 | case 2: ...
|
||||||
|
10 | match x:
|
||||||
|
11 | case enum.variant | var: ... # or pattern with irrefutable part
|
||||||
|
| ^^^ Syntax Error: name capture `var` makes remaining patterns unreachable
|
||||||
|
12 | case 2: ...
|
||||||
|
|
|
|
@ -0,0 +1,230 @@
|
||||||
|
---
|
||||||
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
|
input_file: crates/ruff_python_parser/resources/inline/ok/irrefutable_case_pattern_at_end.py
|
||||||
|
---
|
||||||
|
## AST
|
||||||
|
|
||||||
|
```
|
||||||
|
Module(
|
||||||
|
ModModule {
|
||||||
|
range: 0..176,
|
||||||
|
body: [
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 0..42,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 6..7,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
|
MatchCase {
|
||||||
|
range: 13..24,
|
||||||
|
pattern: MatchValue(
|
||||||
|
PatternMatchValue {
|
||||||
|
range: 18..19,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 18..19,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 21..24,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 21..24,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 29..42,
|
||||||
|
pattern: MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 34..37,
|
||||||
|
pattern: None,
|
||||||
|
name: Some(
|
||||||
|
Identifier {
|
||||||
|
id: Name("var"),
|
||||||
|
range: 34..37,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 39..42,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 39..42,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 43..83,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 49..50,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
|
MatchCase {
|
||||||
|
range: 56..67,
|
||||||
|
pattern: MatchValue(
|
||||||
|
PatternMatchValue {
|
||||||
|
range: 61..62,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 61..62,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 64..67,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 64..67,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 72..83,
|
||||||
|
pattern: MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 77..78,
|
||||||
|
pattern: None,
|
||||||
|
name: None,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 80..83,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 80..83,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 84..175,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 90..91,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
|
MatchCase {
|
||||||
|
range: 97..118,
|
||||||
|
pattern: MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 102..105,
|
||||||
|
pattern: None,
|
||||||
|
name: Some(
|
||||||
|
Identifier {
|
||||||
|
id: Name("var"),
|
||||||
|
range: 102..105,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: Some(
|
||||||
|
BooleanLiteral(
|
||||||
|
ExprBooleanLiteral {
|
||||||
|
range: 109..113,
|
||||||
|
value: true,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 115..118,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 115..118,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 164..175,
|
||||||
|
pattern: MatchValue(
|
||||||
|
PatternMatchValue {
|
||||||
|
range: 169..170,
|
||||||
|
value: NumberLiteral(
|
||||||
|
ExprNumberLiteral {
|
||||||
|
range: 169..170,
|
||||||
|
value: Int(
|
||||||
|
2,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 172..175,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 172..175,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
```
|
|
@ -1,18 +1,17 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
input_file: crates/ruff_python_parser/resources/inline/ok/match_as_pattern.py
|
input_file: crates/ruff_python_parser/resources/inline/ok/match_as_pattern.py
|
||||||
snapshot_kind: text
|
|
||||||
---
|
---
|
||||||
## AST
|
## AST
|
||||||
|
|
||||||
```
|
```
|
||||||
Module(
|
Module(
|
||||||
ModModule {
|
ModModule {
|
||||||
range: 0..49,
|
range: 0..60,
|
||||||
body: [
|
body: [
|
||||||
Match(
|
Match(
|
||||||
StmtMatch {
|
StmtMatch {
|
||||||
range: 0..48,
|
range: 0..32,
|
||||||
subject: Name(
|
subject: Name(
|
||||||
ExprName {
|
ExprName {
|
||||||
range: 6..9,
|
range: 6..9,
|
||||||
|
@ -49,11 +48,25 @@ Module(
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 33..59,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 39..42,
|
||||||
|
id: Name("foo"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
MatchCase {
|
MatchCase {
|
||||||
range: 37..48,
|
range: 48..59,
|
||||||
pattern: MatchAs(
|
pattern: MatchAs(
|
||||||
PatternMatchAs {
|
PatternMatchAs {
|
||||||
range: 42..43,
|
range: 53..54,
|
||||||
pattern: None,
|
pattern: None,
|
||||||
name: None,
|
name: None,
|
||||||
},
|
},
|
||||||
|
@ -62,10 +75,10 @@ Module(
|
||||||
body: [
|
body: [
|
||||||
Expr(
|
Expr(
|
||||||
StmtExpr {
|
StmtExpr {
|
||||||
range: 45..48,
|
range: 56..59,
|
||||||
value: EllipsisLiteral(
|
value: EllipsisLiteral(
|
||||||
ExprEllipsisLiteral {
|
ExprEllipsisLiteral {
|
||||||
range: 45..48,
|
range: 56..59,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
input_file: crates/ruff_python_parser/resources/inline/ok/match_as_pattern_soft_keyword.py
|
input_file: crates/ruff_python_parser/resources/inline/ok/match_as_pattern_soft_keyword.py
|
||||||
snapshot_kind: text
|
|
||||||
---
|
---
|
||||||
## AST
|
## AST
|
||||||
|
|
||||||
```
|
```
|
||||||
Module(
|
Module(
|
||||||
ModModule {
|
ModModule {
|
||||||
range: 0..69,
|
range: 0..91,
|
||||||
body: [
|
body: [
|
||||||
Match(
|
Match(
|
||||||
StmtMatch {
|
StmtMatch {
|
||||||
range: 0..68,
|
range: 0..29,
|
||||||
subject: Name(
|
subject: Name(
|
||||||
ExprName {
|
ExprName {
|
||||||
range: 6..9,
|
range: 6..9,
|
||||||
|
@ -49,16 +48,30 @@ Module(
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 30..60,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 36..39,
|
||||||
|
id: Name("foo"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
MatchCase {
|
MatchCase {
|
||||||
range: 34..49,
|
range: 45..60,
|
||||||
pattern: MatchAs(
|
pattern: MatchAs(
|
||||||
PatternMatchAs {
|
PatternMatchAs {
|
||||||
range: 39..44,
|
range: 50..55,
|
||||||
pattern: None,
|
pattern: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
Identifier {
|
Identifier {
|
||||||
id: Name("match"),
|
id: Name("match"),
|
||||||
range: 39..44,
|
range: 50..55,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -67,26 +80,40 @@ Module(
|
||||||
body: [
|
body: [
|
||||||
Expr(
|
Expr(
|
||||||
StmtExpr {
|
StmtExpr {
|
||||||
range: 46..49,
|
range: 57..60,
|
||||||
value: EllipsisLiteral(
|
value: EllipsisLiteral(
|
||||||
ExprEllipsisLiteral {
|
ExprEllipsisLiteral {
|
||||||
range: 46..49,
|
range: 57..60,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Match(
|
||||||
|
StmtMatch {
|
||||||
|
range: 61..90,
|
||||||
|
subject: Name(
|
||||||
|
ExprName {
|
||||||
|
range: 67..70,
|
||||||
|
id: Name("foo"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
cases: [
|
||||||
MatchCase {
|
MatchCase {
|
||||||
range: 54..68,
|
range: 76..90,
|
||||||
pattern: MatchAs(
|
pattern: MatchAs(
|
||||||
PatternMatchAs {
|
PatternMatchAs {
|
||||||
range: 59..63,
|
range: 81..85,
|
||||||
pattern: None,
|
pattern: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
Identifier {
|
Identifier {
|
||||||
id: Name("type"),
|
id: Name("type"),
|
||||||
range: 59..63,
|
range: 81..85,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -95,10 +122,10 @@ Module(
|
||||||
body: [
|
body: [
|
||||||
Expr(
|
Expr(
|
||||||
StmtExpr {
|
StmtExpr {
|
||||||
range: 65..68,
|
range: 87..90,
|
||||||
value: EllipsisLiteral(
|
value: EllipsisLiteral(
|
||||||
ExprEllipsisLiteral {
|
ExprEllipsisLiteral {
|
||||||
range: 65..68,
|
range: 87..90,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
---
|
---
|
||||||
source: crates/ruff_python_parser/tests/fixtures.rs
|
source: crates/ruff_python_parser/tests/fixtures.rs
|
||||||
input_file: crates/ruff_python_parser/resources/inline/ok/match_sequence_pattern_terminator.py
|
input_file: crates/ruff_python_parser/resources/inline/ok/match_sequence_pattern_terminator.py
|
||||||
snapshot_kind: text
|
|
||||||
---
|
---
|
||||||
## AST
|
## AST
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ Module(
|
||||||
),
|
),
|
||||||
cases: [
|
cases: [
|
||||||
MatchCase {
|
MatchCase {
|
||||||
range: 19..30,
|
range: 19..35,
|
||||||
pattern: MatchAs(
|
pattern: MatchAs(
|
||||||
PatternMatchAs {
|
PatternMatchAs {
|
||||||
range: 24..25,
|
range: 24..25,
|
||||||
|
@ -35,82 +34,54 @@ Module(
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
guard: None,
|
|
||||||
body: [
|
|
||||||
Expr(
|
|
||||||
StmtExpr {
|
|
||||||
range: 27..30,
|
|
||||||
value: EllipsisLiteral(
|
|
||||||
ExprEllipsisLiteral {
|
|
||||||
range: 27..30,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
MatchCase {
|
|
||||||
range: 35..51,
|
|
||||||
pattern: MatchAs(
|
|
||||||
PatternMatchAs {
|
|
||||||
range: 40..41,
|
|
||||||
pattern: None,
|
|
||||||
name: Some(
|
|
||||||
Identifier {
|
|
||||||
id: Name("a"),
|
|
||||||
range: 40..41,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
guard: Some(
|
guard: Some(
|
||||||
Name(
|
Name(
|
||||||
ExprName {
|
ExprName {
|
||||||
|
range: 29..30,
|
||||||
|
id: Name("x"),
|
||||||
|
ctx: Load,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 32..35,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 32..35,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 40..54,
|
||||||
|
pattern: MatchSequence(
|
||||||
|
PatternMatchSequence {
|
||||||
|
range: 45..49,
|
||||||
|
patterns: [
|
||||||
|
MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
range: 45..46,
|
range: 45..46,
|
||||||
id: Name("x"),
|
|
||||||
ctx: Load,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
body: [
|
|
||||||
Expr(
|
|
||||||
StmtExpr {
|
|
||||||
range: 48..51,
|
|
||||||
value: EllipsisLiteral(
|
|
||||||
ExprEllipsisLiteral {
|
|
||||||
range: 48..51,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
MatchCase {
|
|
||||||
range: 56..70,
|
|
||||||
pattern: MatchSequence(
|
|
||||||
PatternMatchSequence {
|
|
||||||
range: 61..65,
|
|
||||||
patterns: [
|
|
||||||
MatchAs(
|
|
||||||
PatternMatchAs {
|
|
||||||
range: 61..62,
|
|
||||||
pattern: None,
|
pattern: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
Identifier {
|
Identifier {
|
||||||
id: Name("a"),
|
id: Name("a"),
|
||||||
range: 61..62,
|
range: 45..46,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MatchAs(
|
MatchAs(
|
||||||
PatternMatchAs {
|
PatternMatchAs {
|
||||||
range: 64..65,
|
range: 48..49,
|
||||||
pattern: None,
|
pattern: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
Identifier {
|
Identifier {
|
||||||
id: Name("b"),
|
id: Name("b"),
|
||||||
range: 64..65,
|
range: 48..49,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -122,10 +93,10 @@ Module(
|
||||||
body: [
|
body: [
|
||||||
Expr(
|
Expr(
|
||||||
StmtExpr {
|
StmtExpr {
|
||||||
range: 67..70,
|
range: 51..54,
|
||||||
value: EllipsisLiteral(
|
value: EllipsisLiteral(
|
||||||
ExprEllipsisLiteral {
|
ExprEllipsisLiteral {
|
||||||
range: 67..70,
|
range: 51..54,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -133,31 +104,31 @@ Module(
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
MatchCase {
|
MatchCase {
|
||||||
range: 75..94,
|
range: 59..78,
|
||||||
pattern: MatchSequence(
|
pattern: MatchSequence(
|
||||||
PatternMatchSequence {
|
PatternMatchSequence {
|
||||||
range: 80..84,
|
range: 64..68,
|
||||||
patterns: [
|
patterns: [
|
||||||
MatchAs(
|
MatchAs(
|
||||||
PatternMatchAs {
|
PatternMatchAs {
|
||||||
range: 80..81,
|
range: 64..65,
|
||||||
pattern: None,
|
pattern: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
Identifier {
|
Identifier {
|
||||||
id: Name("a"),
|
id: Name("a"),
|
||||||
range: 80..81,
|
range: 64..65,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
MatchAs(
|
MatchAs(
|
||||||
PatternMatchAs {
|
PatternMatchAs {
|
||||||
range: 83..84,
|
range: 67..68,
|
||||||
pattern: None,
|
pattern: None,
|
||||||
name: Some(
|
name: Some(
|
||||||
Identifier {
|
Identifier {
|
||||||
id: Name("b"),
|
id: Name("b"),
|
||||||
range: 83..84,
|
range: 67..68,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
@ -168,12 +139,40 @@ Module(
|
||||||
guard: Some(
|
guard: Some(
|
||||||
Name(
|
Name(
|
||||||
ExprName {
|
ExprName {
|
||||||
range: 88..89,
|
range: 72..73,
|
||||||
id: Name("x"),
|
id: Name("x"),
|
||||||
ctx: Load,
|
ctx: Load,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
body: [
|
||||||
|
Expr(
|
||||||
|
StmtExpr {
|
||||||
|
range: 75..78,
|
||||||
|
value: EllipsisLiteral(
|
||||||
|
ExprEllipsisLiteral {
|
||||||
|
range: 75..78,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
MatchCase {
|
||||||
|
range: 83..94,
|
||||||
|
pattern: MatchAs(
|
||||||
|
PatternMatchAs {
|
||||||
|
range: 88..89,
|
||||||
|
pattern: None,
|
||||||
|
name: Some(
|
||||||
|
Identifier {
|
||||||
|
id: Name("a"),
|
||||||
|
range: 88..89,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
guard: None,
|
||||||
body: [
|
body: [
|
||||||
Expr(
|
Expr(
|
||||||
StmtExpr {
|
StmtExpr {
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue