Repository: astral-sh/ruff
File: crates/ty_ide/src/semantic_tokens.rs (Rust)

Code before:
                // Visit the handler body
                self.visit_body(&handler.body);
            }
        }
    }

    fn visit_pattern(&mut self, pattern: &ast::Pattern) {
        match pattern {
            ast::Pattern::MatchAs(pattern_as) => {
                // Visit the nested pattern first to maintain source order
                if let Some(nested_pattern) = &pattern_as.pattern {
                    self.visit_pattern(nested_pattern);
                }

                // Now add the "as" variable name token
                if let Some(name) = &pattern_as.name {
                    self.add_token(
                        name.range(),
                        SemanticTokenType::Variable,
                        SemanticTokenModifier::empty(),
                    );
                }
            }
            ast::Pattern::MatchMapping(pattern_mapping) => {
                // `**rest` can appear before or after the key-value pairs
                // (the parser accepts both, emitting an error for the former).
                let rest_before_keys = pattern_mapping.rest.as_ref().filter(|rest| {
                    pattern_mapping
                        .keys
                        .first()
                        .is_some_and(|key| rest.start() < key.start())
                });
                let rest_after_keys = pattern_mapping.rest.as_ref().filter(|rest| {
                    pattern_mapping
                        .keys
                        .first()
                        .is_none_or(|key| rest.start() >= key.start())
                });

                if let Some(rest_name) = rest_before_keys {
                    self.add_token(
                        rest_name.range(),
                        SemanticTokenType::Variable,
                        SemanticTokenModifier::empty(),
                    );
                }

                for (key, nested_pattern) in
                    pattern_mapping.keys.iter().zip(&pattern_mapping.patterns)
                {
                    self.visit_expr(key);

Review comment (suggestion):
```suggestion
                // (the parser can produce either AST, but emits an
                // invalid-syntax error for the former).
```

Code after:
                // Visit the handler body
                self.visit_body(&handler.body);
            }
        }
    }

    fn visit_pattern(&mut self, pattern: &ast::Pattern) {
        match pattern {
            ast::Pattern::MatchAs(pattern_as) => {
                // Visit the nested pattern first to maintain source order
                if let Some(nested_pattern) = &pattern_as.pattern {
                    self.visit_pattern(nested_pattern);
                }

                // Now add the "as" variable name token
                if let Some(name) = &pattern_as.name {
                    self.add_token(
                        name.range(),
                        SemanticTokenType::Variable,
                        SemanticTokenModifier::empty(),
                    );
                }
            }
            ast::Pattern::MatchMapping(pattern_mapping) => {
                // `**rest` can appear before or after the key-value pairs
                // (the parser can produce either AST, but emits an
                // invalid-syntax error for the former).
                let rest_before_keys = pattern_mapping.rest.as_ref().filter(|rest| {
                    pattern_mapping
                        .keys
                        .first()
                        .is_some_and(|key| rest.start() < key.start())
                });
                let rest_after_keys = pattern_mapping.rest.as_ref().filter(|rest| {
                    pattern_mapping
                        .keys
                        .first()
                        .is_none_or(|key| rest.start() >= key.start())
                });

                if let Some(rest_name) = rest_before_keys {
                    self.add_token(
                        rest_name.range(),
                        SemanticTokenType::Variable,
                        SemanticTokenModifier::empty(),
                    );
                }

                for (key, nested_pattern) in
                    pattern_mapping.keys.iter().zip(&pattern_mapping.patterns)
                {