1
1
// Decoding metadata from a single crate's metadata
2
2
3
3
use std::iter::TrustedLen;
4
- use std::path::Path;
4
+ use std::path::{ Path, PathBuf} ;
5
5
use std::sync::{Arc, OnceLock};
6
6
use std::{io, iter, mem};
7
7
@@ -1610,10 +1610,14 @@ impl<'a> CrateMetadataRef<'a> {
1610
1610
/// Proc macro crates don't currently export spans, so this function does not have
1611
1611
/// to work for them.
1612
1612
fn imported_source_file(self, source_file_index: u32, sess: &Session) -> ImportedSourceFile {
1613
- fn filter<'a>(sess: &Session, path: Option<&'a Path>) -> Option<&'a Path> {
1613
+ fn filter<'a>(
1614
+ sess: &Session,
1615
+ real_source_base_dir: &Option<PathBuf>,
1616
+ path: Option<&'a Path>,
1617
+ ) -> Option<&'a Path> {
1614
1618
path.filter(|_| {
1615
1619
// Only spend time on further checks if we have what to translate *to*.
1616
- sess.opts.real_rust_source_base_dir .is_some()
1620
+ real_source_base_dir .is_some()
1617
1621
// Some tests need the translation to be always skipped.
1618
1622
&& sess.opts.unstable_opts.translate_remapped_path_to_local_path
1619
1623
})
@@ -1625,57 +1629,92 @@ impl<'a> CrateMetadataRef<'a> {
1625
1629
})
1626
1630
}
1627
1631
1628
- let try_to_translate_virtual_to_real = |name: &mut rustc_span::FileName| {
1629
- // Translate the virtual `/rustc/$hash` prefix back to a real directory
1630
- // that should hold actual sources, where possible.
1631
- //
1632
- // NOTE: if you update this, you might need to also update bootstrap's code for generating
1633
- // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
1634
- let virtual_rust_source_base_dir = [
1635
- filter(sess, option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR").map(Path::new)),
1636
- filter(sess, sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref()),
1637
- ];
1632
+ let try_to_translate_virtual_to_real =
1633
+ |virtual_source_base_dir: Option<&str>,
1634
+ real_source_base_dir: &Option<PathBuf>,
1635
+ name: &mut rustc_span::FileName| {
1636
+ let virtual_source_base_dir = [
1637
+ filter(sess, real_source_base_dir, virtual_source_base_dir.map(Path::new)),
1638
+ filter(
1639
+ sess,
1640
+ real_source_base_dir,
1641
+ sess.opts.unstable_opts.simulate_remapped_rust_src_base.as_deref(),
1642
+ ),
1643
+ ];
1638
1644
1639
- debug!(
1640
- "try_to_translate_virtual_to_real(name={:?}): \
1641
- virtual_rust_source_base_dir ={:?}, real_rust_source_base_dir ={:?}",
1642
- name, virtual_rust_source_base_dir, sess.opts.real_rust_source_base_dir ,
1643
- );
1645
+ debug!(
1646
+ "try_to_translate_virtual_to_real(name={:?}): \
1647
+ virtual_source_base_dir ={:?}, real_source_base_dir ={:?}",
1648
+ name, virtual_source_base_dir, real_source_base_dir ,
1649
+ );
1644
1650
1645
- for virtual_dir in virtual_rust_source_base_dir.iter().flatten() {
1646
- if let Some(real_dir) = &sess.opts.real_rust_source_base_dir
1651
+ for virtual_dir in virtual_source_base_dir.iter().flatten() {
1652
+ if let Some(real_dir) = &real_source_base_dir
1653
+ && let rustc_span::FileName::Real(old_name) = name
1654
+ && let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
1655
+ old_name
1656
+ && let Ok(rest) = virtual_name.strip_prefix(virtual_dir)
1657
+ {
1658
+ let new_path = real_dir.join(rest);
1659
+
1660
+ debug!(
1661
+ "try_to_translate_virtual_to_real: `{}` -> `{}`",
1662
+ virtual_name.display(),
1663
+ new_path.display(),
1664
+ );
1665
+
1666
+ // Check if the translated real path is affected by any user-requested
1667
+ // remaps via --remap-path-prefix. Apply them if so.
1668
+ // Note that this is a special case for imported rust-src paths specified by
1669
+ // https://rust-lang.github.io/rfcs/3127-trim-paths.html#handling-sysroot-paths.
1670
+ // Other imported paths are not currently remapped (see #66251).
1671
+ let (user_remapped, applied) =
1672
+ sess.source_map().path_mapping().map_prefix(&new_path);
1673
+ let new_name = if applied {
1674
+ rustc_span::RealFileName::Remapped {
1675
+ local_path: Some(new_path.clone()),
1676
+ virtual_name: user_remapped.to_path_buf(),
1677
+ }
1678
+ } else {
1679
+ rustc_span::RealFileName::LocalPath(new_path)
1680
+ };
1681
+ *old_name = new_name;
1682
+ }
1683
+ }
1684
+ };
1685
+
1686
+ let try_to_translate_real_to_virtual =
1687
+ |virtual_source_base_dir: Option<&str>,
1688
+ real_source_base_dir: &Option<PathBuf>,
1689
+ subdir: &str,
1690
+ name: &mut rustc_span::FileName| {
1691
+ if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base
1692
+ && let Some(real_dir) = real_source_base_dir
1647
1693
&& let rustc_span::FileName::Real(old_name) = name
1648
- && let rustc_span::RealFileName::Remapped { local_path: _, virtual_name } =
1649
- old_name
1650
- && let Ok(rest) = virtual_name.strip_prefix(virtual_dir)
1651
1694
{
1652
- let new_path = real_dir.join(rest);
1653
-
1654
- debug!(
1655
- "try_to_translate_virtual_to_real: `{}` -> `{}`",
1656
- virtual_name.display(),
1657
- new_path.display(),
1658
- );
1659
-
1660
- // Check if the translated real path is affected by any user-requested
1661
- // remaps via --remap-path-prefix. Apply them if so.
1662
- // Note that this is a special case for imported rust-src paths specified by
1663
- // https://rust-lang.github.io/rfcs/3127-trim-paths.html#handling-sysroot-paths.
1664
- // Other imported paths are not currently remapped (see #66251).
1665
- let (user_remapped, applied) =
1666
- sess.source_map().path_mapping().map_prefix(&new_path);
1667
- let new_name = if applied {
1668
- rustc_span::RealFileName::Remapped {
1669
- local_path: Some(new_path.clone()),
1670
- virtual_name: user_remapped.to_path_buf(),
1695
+ let relative_path = match old_name {
1696
+ rustc_span::RealFileName::LocalPath(local) => {
1697
+ local.strip_prefix(real_dir).ok()
1698
+ }
1699
+ rustc_span::RealFileName::Remapped { virtual_name, .. } => {
1700
+ virtual_source_base_dir
1701
+ .and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok())
1671
1702
}
1672
- } else {
1673
- rustc_span::RealFileName::LocalPath(new_path)
1674
1703
};
1675
- *old_name = new_name;
1704
+ debug!(
1705
+ ?relative_path,
1706
+ ?virtual_dir,
1707
+ ?subdir,
1708
+ "simulate_remapped_rust_src_base"
1709
+ );
1710
+ if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok()) {
1711
+ *old_name = rustc_span::RealFileName::Remapped {
1712
+ local_path: None,
1713
+ virtual_name: virtual_dir.join(subdir).join(rest),
1714
+ };
1715
+ }
1676
1716
}
1677
- }
1678
- };
1717
+ };
1679
1718
1680
1719
let mut import_info = self.cdata.source_map_import_info.lock();
1681
1720
for _ in import_info.len()..=(source_file_index as usize) {
@@ -1713,36 +1752,45 @@ impl<'a> CrateMetadataRef<'a> {
1713
1752
// This is useful for testing so that tests about the effects of
1714
1753
// `try_to_translate_virtual_to_real` don't have to worry about how the
1715
1754
// compiler is bootstrapped.
1716
- if let Some(virtual_dir) = &sess.opts.unstable_opts.simulate_remapped_rust_src_base
1717
- && let Some(real_dir) = &sess.opts.real_rust_source_base_dir
1718
- && let rustc_span::FileName::Real(ref mut old_name) = name
1719
- {
1720
- let relative_path = match old_name {
1721
- rustc_span::RealFileName::LocalPath(local) => {
1722
- local.strip_prefix(real_dir).ok()
1723
- }
1724
- rustc_span::RealFileName::Remapped { virtual_name, .. } => {
1725
- option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR")
1726
- .and_then(|virtual_dir| virtual_name.strip_prefix(virtual_dir).ok())
1727
- }
1728
- };
1729
- debug!(?relative_path, ?virtual_dir, "simulate_remapped_rust_src_base");
1730
- for subdir in ["library", "compiler"] {
1731
- if let Some(rest) = relative_path.and_then(|p| p.strip_prefix(subdir).ok())
1732
- {
1733
- *old_name = rustc_span::RealFileName::Remapped {
1734
- local_path: None, // FIXME: maybe we should preserve this?
1735
- virtual_name: virtual_dir.join(subdir).join(rest),
1736
- };
1737
- break;
1738
- }
1739
- }
1740
- }
1755
+ try_to_translate_real_to_virtual(
1756
+ option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"),
1757
+ &sess.opts.real_rust_source_base_dir,
1758
+ "library",
1759
+ &mut name,
1760
+ );
1761
+
1762
+ // If this file is under $sysroot/lib/rustlib/rustc-src/
1763
+ // and the user wish to simulate remapping with -Z simulate-remapped-rust-src-base,
1764
+ // then we change `name` to a similar state as if the rust was bootstrapped
1765
+ // with `remap-debuginfo = true`.
1766
+ try_to_translate_real_to_virtual(
1767
+ option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"),
1768
+ &sess.opts.real_rustc_dev_source_base_dir,
1769
+ "compiler",
1770
+ &mut name,
1771
+ );
1741
1772
1742
1773
// If this file's path has been remapped to `/rustc/$hash`,
1743
- // we might be able to reverse that (also see comments above,
1744
- // on `try_to_translate_virtual_to_real`).
1745
- try_to_translate_virtual_to_real(&mut name);
1774
+ // we might be able to reverse that.
1775
+ //
1776
+ // NOTE: if you update this, you might need to also update bootstrap's code for generating
1777
+ // the `rust-src` component in `Src::run` in `src/bootstrap/dist.rs`.
1778
+ try_to_translate_virtual_to_real(
1779
+ option_env!("CFG_VIRTUAL_RUST_SOURCE_BASE_DIR"),
1780
+ &sess.opts.real_rust_source_base_dir,
1781
+ &mut name,
1782
+ );
1783
+
1784
+ // If this file's path has been remapped to `/rustc-dev/$hash`,
1785
+ // we might be able to reverse that.
1786
+ //
1787
+ // NOTE: if you update this, you might need to also update bootstrap's code for generating
1788
+ // the `rustc-dev` component in `Src::run` in `src/bootstrap/dist.rs`.
1789
+ try_to_translate_virtual_to_real(
1790
+ option_env!("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR"),
1791
+ &sess.opts.real_rustc_dev_source_base_dir,
1792
+ &mut name,
1793
+ );
1746
1794
1747
1795
let local_version = sess.source_map().new_imported_source_file(
1748
1796
name,
0 commit comments