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