{"record":{"id":"404f7f8d23315b21","repo":"rust-lang/rust","slug":"rust-analyzer-analysis-stats-produced-no-pgo-files","errorCode":null,"errorMessage":"rust-analyzer analysis-stats produced no pgo files. This is a bug in rust-analyzer; please file an issue.","messagePattern":"rust-analyzer analysis-stats produced no pgo files\\. This is a bug in rust-analyzer; please file an issue\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/tools/rust-analyzer/xtask/src/pgo.rs","lineNumber":68,"sourceCode":"    )\n    .run()\n    .context(\"cannot generate PGO profiles\")?;\n\n    // Merge profiles into a single file\n    let merged_profile = pgo_dir.join(\"merged.profdata\");\n    let profile_files = std::fs::read_dir(pgo_dir)?\n        .filter_map(|entry| {\n            let entry = entry.ok()?;\n            if entry.path().extension() == Some(OsStr::new(\"profraw\")) {\n                Some(entry.path().to_str().unwrap().to_owned())\n            } else {\n                None\n            }\n        })\n        .collect::<Vec<_>>();\n\n    if profile_files.is_empty() {\n        anyhow::bail!(\n            \"rust-analyzer analysis-stats produced no pgo files. This is a bug in rust-analyzer; please file an issue.\"\n        );\n    }\n\n    cmd!(sh, \"{llvm_profdata} merge {profile_files...} -o {merged_profile}\").run().context(\n        \"cannot merge PGO profiles. Do you have the rustup `llvm-tools` component installed?\",\n    )?;\n\n    Ok(merged_profile)\n}\n\n/// Downloads a crate from GitHub, stores it into `pgo_dir` and returns a path to it.\nfn download_crate_for_training(sh: &Shell, pgo_dir: &Path, repo: &str) -> anyhow::Result<PathBuf> {\n    let mut it = repo.splitn(2, '@');\n    let repo = it.next().unwrap();\n    let revision = it.next();\n\n    // FIXME: switch to `--revision` here around 2035 or so","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/rust-lang/rust/blob/7088e4b63a9516ebfbfe2ab2d999cf01a528ac14/src/tools/rust-analyzer/xtask/src/pgo.rs#L50-L86","documentation":"Bailed by the PGO training step in xtask/pgo.rs when, after running rust-analyzer analysis-stats with profiling instrumentation, no .profraw files appear in the output directory. profraw files are what llvm-profdata merges; their absence means the instrumented analysis-stats run did not actually produce profile data.","triggerScenarios":"Running `cargo xtask pgo` (or the analysis-stats PGO subcommand) where the rust-analyzer binary used was not built with -Cinstrument-coverage / the LLVM_PROFILE_FILE env var was not set correctly, or analysis-stats exited before writing any profile.","commonSituations":"Building rust-analyzer for PGO without the instrumented profile flags; LLVM_PROFILE_FILE pointing at a path the process can't write (read-only dir); analysis-stats crashing early so no basic block is ever executed; a stale pgo_dir that already contained only non-profraw files.","solutions":["Confirm the rust-analyzer binary used for analysis-stats is the instrumented one (built with the PGO instrumentation flags the xtask sets).","Check LLVM_PROFILE_FILE is set to a writable path pattern in the directory pgo_dir reads from, and the directory exists.","Re-run analysis-stats standalone with verbose logging to see if it completed; if it errored, fix that first.","Clear pgo_dir before the run so leftover files don't mask the absence of new profraw files."],"exampleFix":"// before\nif profile_files.is_empty() {\n    anyhow::bail!(\n        \"rust-analyzer analysis-stats produced no pgo files. \\\n         This is a bug in rust-analyzer; please file an issue.\"\n    );\n}\n\n// after: distinguish user-fixable causes from a real r-a bug\nif profile_files.is_empty() {\n    let profraw_glob = pgo_dir.join(\"*.profraw\");\n    anyhow::bail!(\n        \"rust-analyzer analysis-stats produced no pgo files (looked for {}). \\\n         Verify the binary was built with instrumentation and \\\n         LLVM_PROFILE_FILE was set; only file an r-a issue if both are correct.\",\n        profraw_glob.display()\n    );\n}","handlingStrategy":"validation","validationCode":"// Before the PGO run, confirm the r-a binary is instrumented and the profile\n// dir is writable:\nfn instrumented_and_writable(bin: &Path, dir: &Path) -> bool {\n    let instr = std::process::Command::new(bin).arg(\"--version\")\n        .output().map(|o| String::from_utf8_lossy(&o.stdout).contains(\"instrumented\")).unwrap_or(false);\n    instr && std::fs::create_dir_all(dir).is_ok()\n}\n// Also export LLVM_PROFILE_FILE=\"<dir>/%m-%p.profraw\".","typeGuard":"null","tryCatchPattern":"match pgo::build(&sh, &pgo_dir) {\n    Ok(_) => Ok(()),\n    Err(e) if e.to_string().contains(\"no pgo files\") => {\n        eprintln!(\"ensure the r-a binary is instrumented and LLVM_PROFILE_FILE is set\");\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Build rust-analyzer with the PGO instrumentation flags the xtask sets.","Set LLVM_PROFILE_FILE to a writable path pattern in pgo_dir.","Clear pgo_dir before each run so stale files don't mask a missing-profraw condition."],"tags":["rust-analyzer","pgo","profiling","xtask","llvm"],"backgroundTag":null,"analyzedSha":"7088e4b63a9516ebfbfe2ab2d999cf01a528ac14","analyzedAt":"2026-08-10T14:17:03.603Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}