Fix the API check for Rust doc examples

Review the AI's codeMedium15 minAnthropic style

Your task

An AI wrote usage docs for your Rust crate. The prose is good, but one example calls client.fetch_all() and another RetryPolicy::exponential(), and the crate has neither. They look like real methods because they follow the usual naming. Until every example runs as a doctest in CI, your team checks the examples against the crate's real symbol table.

An assistant wrote find_hallucinated_api_calls(known_symbols, example_lines). It is in the editor. It has a bug. Find it and fix it.

Input and output:

  • known_symbols: every callable the crate really has, written as it is called: a bare method name like fetch_page, or a path like Client::connect.
  • example_lines: the code lines of the doc examples.
  • Return each name the examples call that is not a known symbol, once each, sorted by plain character order.

Rules the tests check:

  • Every ( in a line is a call site. Its name is the run of characters just before the ( made only of ASCII letters, digits, _ and :. So client.fetch_all( names fetch_all, and RetryPolicy::exponential( names RetryPolicy::exponential. Remove any : at the start of the name, then check it against the rules below.
  • Skip a call site whose name is empty, as after a macro like println!( or in (b + c).
  • Skip the keywords if, while, for, match, return, let and fn.
  • Skip a definition: the name follows the word fn with only spaces or tabs between them, as in fn main(. fn must be a whole word, so the character before it, if any, is not a letter, digit, _ or :.
  • Trim each known symbol. A call is real only when its whole name equals a known symbol exactly, case included. Client::new being known does not make Config::new real.

Examples

find_hallucinated_api_calls(known_symbols: list[str], example_lines: list[str]) -> list[str]
Example 1
Inputfind_hallucinated_api_calls(["Client::connect", "fetch_page", "RetryPolicy::new", "build"], ["let client = Client::connect(url)?;", "let all = client.fetch_all().await?;", "let policy = RetryPolicy::exponential().build();"])
Output["RetryPolicy::exponential", "fetch_all"]
Example 2
Inputfind_hallucinated_api_calls(["fetch_page"], ["let page = client.fetch_page(1)?;", "println!(\"{}\", page);"])
Output[]
Example 3
Inputfind_hallucinated_api_calls([], [])
Output[]