Merge pull request #19588 from Hmikihiro/ext_func_module

fix: `Extract into` function include inline variable in fmt macro
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 8452420..79fb7a2 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -46,17 +46,25 @@
         with:
           ref: ${{ github.event.pull_request.head.sha }}
 
+      - name: Install rustup-toolchain-install-master
+        run: cargo install rustup-toolchain-install-master@1.6.0
+
+      # Install a pinned rustc commit to avoid surprises
       - name: Install Rust toolchain
         run: |
-          rustup update --no-self-update nightly
-          rustup default nightly
-          rustup component add --toolchain nightly rust-src rustfmt
+          RUSTC_VERSION=`cat rust-version`
+          rustup-toolchain-install-master ${RUSTC_VERSION} -c rust-src -c rustfmt
+          rustup default ${RUSTC_VERSION}
+
+      # Emulate a nightly toolchain, because the toolchain installed above does not have "nightly"
+      # in its version string.
+      - name: Emulate a nightly toolchain
+        run: echo "RUSTC_BOOTSTRAP=1" >> $GITHUB_ENV
+
       # https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/rust.json
       - name: Install Rust Problem Matcher
         run: echo "::add-matcher::.github/rust.json"
 
-      # We don't cache this job, as it will be invalidated every day due to nightly usage
-
       - name: Test
         run: cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet
 
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
index c76d3da..fd4eb9e 100644
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -29,15 +29,20 @@
           - os: windows-latest
             target: x86_64-pc-windows-msvc
             code-target: win32-x64
+            pgo: clap-rs/clap
           - os: windows-latest
             target: i686-pc-windows-msvc
+            pgo: clap-rs/clap
           - os: windows-latest
             target: aarch64-pc-windows-msvc
             code-target: win32-arm64
           - os: ubuntu-latest
             target: x86_64-unknown-linux-gnu
-            zig_target: x86_64-unknown-linux-gnu.2.28
+            # Use a container with glibc 2.28
+            # Zig is not used because it doesn't work with PGO
+            container: quay.io/pypa/manylinux_2_28_x86_64
             code-target: linux-x64
+            pgo: clap-rs/clap
           - os: ubuntu-latest
             target: aarch64-unknown-linux-gnu
             zig_target: aarch64-unknown-linux-gnu.2.28
@@ -71,6 +76,12 @@
         with:
           node-version: 22
 
+      - name: Install rustup
+        if: ${{ matrix.container }}
+        run: |
+          curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
+          echo "$HOME/.cargo/bin" >> $GITHUB_PATH
+
       - name: Install Rust toolchain
         run: |
           rustup update --no-self-update stable
@@ -88,11 +99,11 @@
 
       - name: Dist (plain)
         if: ${{ !matrix.zig_target }}
-        run: cargo xtask dist --client-patch-version ${{ github.run_number }} ${{ matrix.pgo && '--pgo' || ''}}
+        run: cargo xtask dist --client-patch-version ${{ github.run_number }} ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || ''}}
 
       - name: Dist (using zigbuild)
         if: ${{ matrix.zig_target }}
-        run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig ${{ matrix.pgo && '--pgo' || ''}}
+        run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || ''}}
 
       - run: npm ci
         working-directory: editors/code
diff --git a/crates/hir-expand/src/proc_macro.rs b/crates/hir-expand/src/proc_macro.rs
index 4920d90..8a1a33d 100644
--- a/crates/hir-expand/src/proc_macro.rs
+++ b/crates/hir-expand/src/proc_macro.rs
@@ -253,7 +253,6 @@
         self.proc_macro_id == Self::PROC_MACRO_ATTR_DISABLED
     }
 
-    /// The macro is explicitly disabled due to proc-macro attribute expansion being disabled.
     pub fn as_expand_error(&self, def_crate: Crate) -> Option<ExpandErrorKind> {
         match self.proc_macro_id {
             Self::PROC_MACRO_ATTR_DISABLED => Some(ExpandErrorKind::ProcMacroAttrExpansionDisabled),
diff --git a/xtask/src/dist.rs b/xtask/src/dist.rs
index a072442..7e26167 100644
--- a/xtask/src/dist.rs
+++ b/xtask/src/dist.rs
@@ -12,6 +12,7 @@
 use xshell::{Cmd, Shell, cmd};
 use zip::{DateTime, ZipWriter, write::SimpleFileOptions};
 
+use crate::flags::PgoTrainingCrate;
 use crate::{
     date_iso,
     flags::{self, Malloc},
@@ -93,7 +94,7 @@
     target: &Target,
     allocator: Malloc,
     zig: bool,
-    pgo: bool,
+    pgo: Option<PgoTrainingCrate>,
 ) -> anyhow::Result<()> {
     let _e = sh.push_env("CFG_RELEASE", release);
     let _e = sh.push_env("CARGO_PROFILE_RELEASE_LTO", "thin");
@@ -111,11 +112,12 @@
     let features = allocator.to_features();
     let command = if linux_target && zig { "zigbuild" } else { "build" };
 
-    let pgo_profile = if pgo {
+    let pgo_profile = if let Some(train_crate) = pgo {
         Some(gather_pgo_profile(
             sh,
             build_command(sh, command, &target_name, features),
             &target_name,
+            train_crate,
         )?)
     } else {
         None
@@ -155,8 +157,9 @@
     sh: &'a Shell,
     ra_build_cmd: Cmd<'a>,
     target: &str,
+    train_crate: PgoTrainingCrate,
 ) -> anyhow::Result<PathBuf> {
-    let pgo_dir = std::path::absolute("ra-pgo-profiles")?;
+    let pgo_dir = std::path::absolute("rust-analyzer-pgo")?;
     // Clear out any stale profiles
     if pgo_dir.is_dir() {
         std::fs::remove_dir_all(&pgo_dir)?;
@@ -168,18 +171,25 @@
         .read()
         .context("cannot resolve target-libdir from rustc")?;
     let target_bindir = PathBuf::from(target_libdir).parent().unwrap().join("bin");
-    let llvm_profdata = target_bindir.join(format!("llvm-profdata{}", EXE_EXTENSION));
+    let llvm_profdata = target_bindir.join("llvm-profdata").with_extension(EXE_EXTENSION);
 
     // Build RA with PGO instrumentation
     let cmd_gather =
         ra_build_cmd.env("RUSTFLAGS", format!("-Cprofile-generate={}", pgo_dir.to_str().unwrap()));
     cmd_gather.run().context("cannot build rust-analyzer with PGO instrumentation")?;
 
-    // Run RA on itself to gather profiles
-    let train_crate = ".";
+    let (train_path, label) = match &train_crate {
+        PgoTrainingCrate::RustAnalyzer => (PathBuf::from("."), "itself"),
+        PgoTrainingCrate::GitHub(url) => {
+            (download_crate_for_training(sh, &pgo_dir, url)?, url.as_str())
+        }
+    };
+
+    // Run RA either on itself or on a downloaded crate
+    eprintln!("Training RA on {label}...");
     cmd!(
         sh,
-        "target/{target}/release/rust-analyzer analysis-stats {train_crate} --run-all-ide-things"
+        "target/{target}/release/rust-analyzer analysis-stats -q --run-all-ide-things {train_path}"
     )
     .run()
     .context("cannot generate PGO profiles")?;
@@ -201,6 +211,17 @@
     Ok(merged_profile)
 }
 
+/// Downloads a crate from GitHub, stores it into `pgo_dir` and returns a path to it.
+fn download_crate_for_training(sh: &Shell, pgo_dir: &Path, url: &str) -> anyhow::Result<PathBuf> {
+    let normalized_path = url.replace("/", "-");
+    let target_path = pgo_dir.join(normalized_path);
+    cmd!(sh, "git clone --depth 1 https://github.com/{url} {target_path}")
+        .run()
+        .with_context(|| "cannot download PGO training crate from {url}")?;
+
+    Ok(target_path)
+}
+
 fn gzip(src_path: &Path, dest_path: &Path) -> anyhow::Result<()> {
     let mut encoder = GzEncoder::new(File::create(dest_path)?, Compression::best());
     let mut input = io::BufReader::new(File::open(src_path)?);
diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs
index 81b6a1b..700806d 100644
--- a/xtask/src/flags.rs
+++ b/xtask/src/flags.rs
@@ -60,7 +60,7 @@
             /// Use cargo-zigbuild
             optional --zig
             /// Apply PGO optimizations
-            optional --pgo
+            optional --pgo pgo: PgoTrainingCrate
         }
         /// Read a changelog AsciiDoc file and update the GitHub Releases entry in Markdown.
         cmd publish-release-notes {
@@ -144,12 +144,31 @@
 }
 
 #[derive(Debug)]
+pub enum PgoTrainingCrate {
+    // Use RA's own sources for PGO training
+    RustAnalyzer,
+    // Download a Rust crate from `https://github.com/{0}` and use it for PGO training.
+    GitHub(String),
+}
+
+impl FromStr for PgoTrainingCrate {
+    type Err = String;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        match s {
+            "rust-analyzer" => Ok(Self::RustAnalyzer),
+            url => Ok(Self::GitHub(url.to_owned())),
+        }
+    }
+}
+
+#[derive(Debug)]
 pub struct Dist {
     pub mimalloc: bool,
     pub jemalloc: bool,
     pub client_patch_version: Option<String>,
     pub zig: bool,
-    pub pgo: bool,
+    pub pgo: Option<PgoTrainingCrate>,
 }
 
 #[derive(Debug)]