Skip to content

Commit 77f5542

Browse files
committed
Overhaul filename handling for cross-compiler consistency
This commit refactors `SourceMap` and most importantly `RealFileName` to make it self-contained in order to achieve cross-compiler consistency. This is achieved: - by making `RealFileName` immutable - by only having `SourceMap::to_real_filename` create `RealFileName` - by also making `RealFileName` holds it's working directory, it's embeddable name and the remapped scopes - by making most `FileName` and `RealFileName` methods take a scope as an argument In order for `SourceMap::to_real_filename` to know which scopes to apply `FilePathMapping` now takes the current remapping scopes to apply, which makes `FileNameDisplayPreference` and company useless and are removed. The scopes type `RemapPathScopeComponents` was moved from `rustc_session::config` to `rustc_span`. The previous system for scoping the local/remapped filenames `RemapFileNameExt::for_scope` is no longer useful as it's replaced by methods on `FileName` and `RealFileName`.
1 parent 2f02462 commit 77f5542

File tree

29 files changed

+742
-714
lines changed

29 files changed

+742
-714
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4631,7 +4631,6 @@ dependencies = [
46314631
name = "rustc_session"
46324632
version = "0.0.0"
46334633
dependencies = [
4634-
"bitflags",
46354634
"getopts",
46364635
"libc",
46374636
"rand 0.9.2",
@@ -4658,6 +4657,7 @@ dependencies = [
46584657
name = "rustc_span"
46594658
version = "0.0.0"
46604659
dependencies = [
4660+
"bitflags",
46614661
"blake3",
46624662
"derive-where",
46634663
"indexmap",

compiler/rustc_builtin_macros/src/source_util.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,13 +68,10 @@ pub(crate) fn expand_file(
6868
let topmost = cx.expansion_cause().unwrap_or(sp);
6969
let loc = cx.source_map().lookup_char_pos(topmost.lo());
7070

71-
use rustc_session::RemapFileNameExt;
72-
use rustc_session::config::RemapPathScopeComponents;
71+
use rustc_span::RemapPathScopeComponents;
7372
ExpandResult::Ready(MacEager::expr(cx.expr_str(
7473
topmost,
75-
Symbol::intern(
76-
&loc.file.name.for_scope(cx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(),
77-
),
74+
Symbol::intern(&loc.file.name.display(RemapPathScopeComponents::MACRO).to_string_lossy()),
7875
)))
7976
}
8077

compiler/rustc_builtin_macros/src/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_errors::{Applicability, Diag, Level};
1111
use rustc_expand::base::*;
1212
use rustc_hir::Attribute;
1313
use rustc_hir::attrs::AttributeKind;
14-
use rustc_span::{ErrorGuaranteed, FileNameDisplayPreference, Ident, Span, Symbol, sym};
14+
use rustc_span::{ErrorGuaranteed, Ident, RemapPathScopeComponents, Span, Symbol, sym};
1515
use thin_vec::{ThinVec, thin_vec};
1616
use tracing::debug;
1717

@@ -445,7 +445,7 @@ fn get_location_info(cx: &ExtCtxt<'_>, fn_: &ast::Fn) -> (Symbol, usize, usize,
445445
cx.sess.source_map().span_to_location_info(span);
446446

447447
let file_name = match source_file {
448-
Some(sf) => sf.name.display(FileNameDisplayPreference::Remapped).to_string(),
448+
Some(sf) => sf.name.display(RemapPathScopeComponents::MACRO).to_string(),
449449
None => "no-location".to_string(),
450450
};
451451

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ use rustc_errors::{DiagCtxtHandle, Level};
2121
use rustc_fs_util::{link_or_copy, path_to_c_string};
2222
use rustc_middle::ty::TyCtxt;
2323
use rustc_session::Session;
24-
use rustc_session::config::{
25-
self, Lto, OutputType, Passes, RemapPathScopeComponents, SplitDwarfKind, SwitchWithOptPath,
26-
};
27-
use rustc_span::{BytePos, InnerSpan, Pos, SpanData, SyntaxContext, sym};
24+
use rustc_session::config::{self, Lto, OutputType, Passes, SplitDwarfKind, SwitchWithOptPath};
25+
use rustc_span::{BytePos, InnerSpan, Pos, RemapPathScopeComponents, SpanData, SyntaxContext, sym};
2826
use rustc_target::spec::{
2927
Arch, CodeModel, FloatAbi, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel,
3028
};
@@ -248,6 +246,7 @@ pub(crate) fn target_machine_factory(
248246
!sess.opts.unstable_opts.use_ctors_section.unwrap_or(sess.target.use_ctors_section);
249247

250248
let path_mapping = sess.source_map().path_mapping().clone();
249+
let working_dir = sess.source_map().working_dir().clone();
251250

252251
let use_emulated_tls = matches!(sess.tls_model(), TlsModel::Emulated);
253252

@@ -271,9 +270,6 @@ pub(crate) fn target_machine_factory(
271270
}
272271
};
273272

274-
let file_name_display_preference =
275-
sess.filename_display_preference(RemapPathScopeComponents::DEBUGINFO);
276-
277273
let use_wasm_eh = wants_wasm_eh(sess);
278274

279275
let prof = SelfProfilerRef::clone(&sess.prof);
@@ -284,8 +280,9 @@ pub(crate) fn target_machine_factory(
284280
let path_to_cstring_helper = |path: Option<PathBuf>| -> CString {
285281
let path = path.unwrap_or_default();
286282
let path = path_mapping
287-
.to_real_filename(path)
288-
.to_string_lossy(file_name_display_preference)
283+
.to_real_filename(&working_dir, path)
284+
.path(RemapPathScopeComponents::DEBUGINFO)
285+
.to_string_lossy()
289286
.into_owned();
290287
CString::new(path).unwrap()
291288
};

compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,7 @@ use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
77
use rustc_data_structures::fx::FxIndexMap;
88
use rustc_index::IndexVec;
99
use rustc_middle::ty::TyCtxt;
10-
use rustc_session::RemapFileNameExt;
11-
use rustc_session::config::RemapPathScopeComponents;
12-
use rustc_span::{SourceFile, StableSourceFileId};
10+
use rustc_span::{RemapPathScopeComponents, SourceFile, StableSourceFileId};
1311
use tracing::debug;
1412

1513
use crate::common::CodegenCx;
@@ -127,10 +125,7 @@ impl GlobalFileTable {
127125

128126
for file in all_files {
129127
raw_file_table.entry(file.stable_id).or_insert_with(|| {
130-
file.name
131-
.for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE)
132-
.to_string_lossy()
133-
.into_owned()
128+
file.name.display(RemapPathScopeComponents::COVERAGE).to_string_lossy().into_owned()
134129
});
135130
}
136131

@@ -145,9 +140,10 @@ impl GlobalFileTable {
145140
// resolve any other entries that are stored as relative paths.
146141
let base_dir = tcx
147142
.sess
148-
.opts
149-
.working_dir
150-
.for_scope(tcx.sess, RemapPathScopeComponents::COVERAGE)
143+
.psess
144+
.source_map()
145+
.working_dir()
146+
.path(RemapPathScopeComponents::COVERAGE)
151147
.to_string_lossy();
152148
table.push(base_dir.as_ref());
153149

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 32 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::borrow::Cow;
22
use std::fmt::{self, Write};
33
use std::hash::{Hash, Hasher};
4-
use std::path::{Path, PathBuf};
4+
use std::path::PathBuf;
55
use std::sync::Arc;
66
use std::{iter, ptr};
77

@@ -19,9 +19,7 @@ use rustc_middle::ty::{
1919
self, AdtKind, CoroutineArgsExt, ExistentialTraitRef, Instance, Ty, TyCtxt, Visibility,
2020
};
2121
use rustc_session::config::{self, DebugInfo, Lto};
22-
use rustc_span::{
23-
DUMMY_SP, FileName, FileNameDisplayPreference, SourceFile, Span, Symbol, hygiene,
24-
};
22+
use rustc_span::{DUMMY_SP, FileName, RemapPathScopeComponents, SourceFile, Span, Symbol, hygiene};
2523
use rustc_symbol_mangling::typeid_for_trait_ref;
2624
use rustc_target::spec::DebuginfoKind;
2725
use smallvec::smallvec;
@@ -555,79 +553,38 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi
555553
) -> &'ll DIFile {
556554
debug!(?source_file.name);
557555

558-
let filename_display_preference =
559-
cx.sess().filename_display_preference(RemapPathScopeComponents::DEBUGINFO);
560-
561-
use rustc_session::config::RemapPathScopeComponents;
562556
let (directory, file_name) = match &source_file.name {
563557
FileName::Real(filename) => {
564-
let working_directory = &cx.sess().opts.working_dir;
565-
debug!(?working_directory);
566-
567-
if filename_display_preference == FileNameDisplayPreference::Remapped {
568-
let filename = cx
569-
.sess()
570-
.source_map()
571-
.path_mapping()
572-
.to_embeddable_absolute_path(filename.clone(), working_directory);
573-
574-
// Construct the absolute path of the file
575-
let abs_path = filename.remapped_path_if_available();
576-
debug!(?abs_path);
577-
578-
if let Ok(rel_path) =
579-
abs_path.strip_prefix(working_directory.remapped_path_if_available())
580-
{
581-
// If the compiler's working directory (which also is the DW_AT_comp_dir of
582-
// the compilation unit) is a prefix of the path we are about to emit, then
583-
// only emit the part relative to the working directory. Because of path
584-
// remapping we sometimes see strange things here: `abs_path` might
585-
// actually look like a relative path (e.g.
586-
// `<crate-name-and-version>/src/lib.rs`), so if we emit it without taking
587-
// the working directory into account, downstream tooling will interpret it
588-
// as `<working-directory>/<crate-name-and-version>/src/lib.rs`, which
589-
// makes no sense. Usually in such cases the working directory will also be
590-
// remapped to `<crate-name-and-version>` or some other prefix of the path
591-
// we are remapping, so we end up with
592-
// `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`.
593-
// By moving the working directory portion into the `directory` part of the
594-
// DIFile, we allow LLVM to emit just the relative path for DWARF, while
595-
// still emitting the correct absolute path for CodeView.
596-
(
597-
working_directory.to_string_lossy(FileNameDisplayPreference::Remapped),
598-
rel_path.to_string_lossy().into_owned(),
599-
)
600-
} else {
601-
("".into(), abs_path.to_string_lossy().into_owned())
602-
}
558+
let (working_directory, embeddable_name) =
559+
filename.embeddable_name(RemapPathScopeComponents::DEBUGINFO);
560+
561+
debug!(?working_directory, ?embeddable_name);
562+
563+
if let Ok(rel_path) = embeddable_name.strip_prefix(working_directory) {
564+
// If the compiler's working directory (which also is the DW_AT_comp_dir of
565+
// the compilation unit) is a prefix of the path we are about to emit, then
566+
// only emit the part relative to the working directory. Because of path
567+
// remapping we sometimes see strange things here: `abs_path` might
568+
// actually look like a relative path (e.g.
569+
// `<crate-name-and-version>/src/lib.rs`), so if we emit it without taking
570+
// the working directory into account, downstream tooling will interpret it
571+
// as `<working-directory>/<crate-name-and-version>/src/lib.rs`, which
572+
// makes no sense. Usually in such cases the working directory will also be
573+
// remapped to `<crate-name-and-version>` or some other prefix of the path
574+
// we are remapping, so we end up with
575+
// `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`.
576+
//
577+
// By moving the working directory portion into the `directory` part of the
578+
// DIFile, we allow LLVM to emit just the relative path for DWARF, while
579+
// still emitting the correct absolute path for CodeView.
580+
(working_directory.to_string_lossy(), rel_path.to_string_lossy().into_owned())
603581
} else {
604-
let working_directory = working_directory.local_path_if_available();
605-
let filename = filename.local_path_if_available();
606-
607-
debug!(?working_directory, ?filename);
608-
609-
let abs_path: Cow<'_, Path> = if filename.is_absolute() {
610-
filename.into()
611-
} else {
612-
let mut p = PathBuf::new();
613-
p.push(working_directory);
614-
p.push(filename);
615-
p.into()
616-
};
617-
618-
if let Ok(rel_path) = abs_path.strip_prefix(working_directory) {
619-
(
620-
working_directory.to_string_lossy(),
621-
rel_path.to_string_lossy().into_owned(),
622-
)
623-
} else {
624-
("".into(), abs_path.to_string_lossy().into_owned())
625-
}
582+
("".into(), embeddable_name.to_string_lossy().into_owned())
626583
}
627584
}
628585
other => {
629586
debug!(?other);
630-
("".into(), other.display(filename_display_preference).to_string())
587+
("".into(), other.display(RemapPathScopeComponents::DEBUGINFO).to_string())
631588
}
632589
};
633590

@@ -889,12 +846,10 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
889846
codegen_unit_name: &str,
890847
debug_context: &CodegenUnitDebugContext<'ll, 'tcx>,
891848
) -> &'ll DIDescriptor {
892-
use rustc_session::RemapFileNameExt;
893-
use rustc_session::config::RemapPathScopeComponents;
894849
let mut name_in_debuginfo = tcx
895850
.sess
896851
.local_crate_source_file()
897-
.map(|src| src.for_scope(&tcx.sess, RemapPathScopeComponents::DEBUGINFO).to_path_buf())
852+
.map(|src| src.path(RemapPathScopeComponents::DEBUGINFO).to_path_buf())
898853
.unwrap_or_else(|| PathBuf::from(tcx.crate_name(LOCAL_CRATE).as_str()));
899854

900855
// To avoid breaking split DWARF, we need to ensure that each codegen unit
@@ -923,12 +878,7 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
923878
let producer = format!("clang LLVM ({rustc_producer})");
924879

925880
let name_in_debuginfo = name_in_debuginfo.to_string_lossy();
926-
let work_dir = tcx
927-
.sess
928-
.opts
929-
.working_dir
930-
.for_scope(tcx.sess, RemapPathScopeComponents::DEBUGINFO)
931-
.to_string_lossy();
881+
let work_dir = tcx.sess.psess.source_map().working_dir();
932882
let output_filenames = tcx.output_filenames(());
933883
let split_name = if tcx.sess.target_can_use_split_dwarf()
934884
&& let Some(f) = output_filenames.split_dwarf_path(
@@ -938,14 +888,15 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
938888
tcx.sess.invocation_temp.as_deref(),
939889
) {
940890
// We get a path relative to the working directory from split_dwarf_path
941-
Some(tcx.sess.source_map().path_mapping().to_real_filename(f))
891+
Some(tcx.sess.source_map().path_mapping().to_real_filename(work_dir, f))
942892
} else {
943893
None
944894
};
945895
let split_name = split_name
946896
.as_ref()
947-
.map(|f| f.for_scope(tcx.sess, RemapPathScopeComponents::DEBUGINFO).to_string_lossy())
897+
.map(|f| f.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy())
948898
.unwrap_or_default();
899+
let work_dir = work_dir.path(RemapPathScopeComponents::DEBUGINFO).to_string_lossy();
949900
let kind = DebugEmissionKind::from_generic(tcx.sess.opts.debuginfo);
950901

951902
let dwarf_version = tcx.sess.dwarf_version();

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -208,15 +208,10 @@ impl<'tcx> CompileTimeInterpCx<'tcx> {
208208
let topmost = span.ctxt().outer_expn().expansion_cause().unwrap_or(span);
209209
let caller = self.tcx.sess.source_map().lookup_char_pos(topmost.lo());
210210

211-
use rustc_session::RemapFileNameExt;
212-
use rustc_session::config::RemapPathScopeComponents;
211+
use rustc_span::RemapPathScopeComponents;
213212
(
214213
Symbol::intern(
215-
&caller
216-
.file
217-
.name
218-
.for_scope(self.tcx.sess, RemapPathScopeComponents::DIAGNOSTICS)
219-
.to_string_lossy(),
214+
&caller.file.name.display(RemapPathScopeComponents::DIAGNOSTICS).to_string_lossy(),
220215
),
221216
u32::try_from(caller.line).unwrap(),
222217
u32::try_from(caller.col_display).unwrap().checked_add(1).unwrap(),

compiler/rustc_driver_impl/src/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> {
181181
}
182182

183183
fn get_source(sess: &Session) -> (String, FileName) {
184-
let src_name = sess.io.input.source_name();
184+
let src_name = sess.io.input.file_name(&sess);
185185
let src = String::clone(
186186
sess.source_map()
187187
.get_source_file(&src_name)

compiler/rustc_errors/src/json.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
use std::error::Report;
1313
use std::io::{self, Write};
14-
use std::path::Path;
14+
use std::path::{Path, PathBuf};
1515
use std::sync::{Arc, Mutex};
1616
use std::vec;
1717

@@ -20,9 +20,9 @@ use derive_setters::Setters;
2020
use rustc_data_structures::sync::IntoDynSyncSend;
2121
use rustc_error_messages::FluentArgs;
2222
use rustc_lint_defs::Applicability;
23-
use rustc_span::Span;
2423
use rustc_span::hygiene::ExpnData;
2524
use rustc_span::source_map::{FilePathMapping, SourceMap};
25+
use rustc_span::{FileName, RealFileName, Span};
2626
use serde::Serialize;
2727

2828
use crate::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
@@ -490,8 +490,14 @@ impl DiagnosticSpan {
490490
None => {
491491
span = rustc_span::DUMMY_SP;
492492
empty_source_map = Arc::new(SourceMap::new(FilePathMapping::empty()));
493-
empty_source_map
494-
.new_source_file(std::path::PathBuf::from("empty.rs").into(), String::new());
493+
empty_source_map.new_source_file(
494+
FileName::Real(
495+
empty_source_map
496+
.path_mapping()
497+
.to_real_filename(&RealFileName::empty(), PathBuf::from("empty.rs")),
498+
),
499+
String::new(),
500+
);
495501
&empty_source_map
496502
}
497503
};

compiler/rustc_expand/src/expand.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
470470
FileName::Real(name) => name
471471
.into_local_path()
472472
.expect("attempting to resolve a file path in an external file"),
473-
other => PathBuf::from(other.prefer_local().to_string()),
473+
other => PathBuf::from(other.prefer_local_unconditionally().to_string()),
474474
};
475475
let dir_path = file_path.parent().unwrap_or(&file_path).to_owned();
476476
self.cx.root_path = dir_path.clone();

0 commit comments

Comments
 (0)