Skip to content

Improve LSP conflict diagnostics with direct rule details#83

Merged
ehwan merged 1 commit into
mainfrom
lsp_error
Jun 23, 2026
Merged

Improve LSP conflict diagnostics with direct rule details#83
ehwan merged 1 commit into
mainfrom
lsp_error

Conversation

@ehwan

@ehwan ehwan commented Jun 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Show the shift and reduce rules directly involved in LSP conflict diagnostics.
  • Remove verbose LR(0) backtrace output from conflict diagnostic messages.
  • Add regression tests for shift/reduce and reduce/reduce LSP conflict diagnostics.
  • Update README editor support notes to mention conflict rule details.

@ehwan ehwan self-assigned this Jun 23, 2026
@ehwan ehwan merged commit 33f5785 into main Jun 23, 2026
1 check passed
@ehwan ehwan deleted the lsp_error branch June 23, 2026 08:34

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances the LSP diagnostics for rusty_lr by including the specific shift and reduce rules involved in conflicts. It introduces helper functions to format LR(0) items and productions, updates the conflict message formatting, and adds comprehensive unit tests to verify the diagnostic output. The reviewer pointed out potential panic risks in format_lr0_item and format_production due to direct indexing of grammar.builder.rules, which could crash the LSP server. It is recommended to use .get() to access these rules safely and handle the None cases gracefully.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +33 to +43
fn format_lr0_item(grammar: &Grammar, item: LR0ItemRef) -> String {
grammar.builder.rules[item.production_idx]
.rule
.clone()
.map(
|class| grammar.class_pretty_name_list(class, 5),
|nonterm| grammar.nonterm_pretty_name(nonterm),
)
.into_shifted(item.dot)
.to_string()
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Direct indexing of grammar.builder.rules with item.production_idx can cause a panic if the index is out of bounds. Since this code runs inside an LSP server, any panic will crash the entire language server process, resulting in a poor user experience. It is safer to use .get() and handle the None case gracefully.

fn format_lr0_item(grammar: &Grammar, item: LR0ItemRef) -> String {
    if let Some(rule) = grammar.builder.rules.get(item.production_idx) {
        rule.rule
            .clone()
            .map(
                |class| grammar.class_pretty_name_list(class, 5),
                |nonterm| grammar.nonterm_pretty_name(nonterm),
            )
            .into_shifted(item.dot)
            .to_string()
    } else {
        format!("<unknown rule {}>", item.production_idx)
    }
}

Comment on lines +45 to +54
fn format_production(grammar: &Grammar, rule: usize) -> String {
grammar.builder.rules[rule]
.rule
.clone()
.map(
|class| grammar.class_pretty_name_list(class, 5),
|nonterm| grammar.nonterm_pretty_name(nonterm),
)
.to_string()
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Direct indexing of grammar.builder.rules with rule can cause a panic if the index is out of bounds. To prevent crashing the LSP server, use .get() to access the rule safely.

fn format_production(grammar: &Grammar, rule: usize) -> String {
    if let Some(rule_info) = grammar.builder.rules.get(rule) {
        rule_info.rule
            .clone()
            .map(
                |class| grammar.class_pretty_name_list(class, 5),
                |nonterm| grammar.nonterm_pretty_name(nonterm),
            )
            .to_string()
    } else {
        format!("<unknown rule {rule}>")
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant