summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_span
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:20:39 +0000
commit1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch)
tree3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /compiler/rustc_span
parentReleasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz
rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_span')
-rw-r--r--compiler/rustc_span/Cargo.toml1
-rw-r--r--compiler/rustc_span/src/def_id.rs6
-rw-r--r--compiler/rustc_span/src/edit_distance.rs32
-rw-r--r--compiler/rustc_span/src/hygiene.rs8
-rw-r--r--compiler/rustc_span/src/lib.rs60
-rw-r--r--compiler/rustc_span/src/profiling.rs16
-rw-r--r--compiler/rustc_span/src/source_map.rs81
-rw-r--r--compiler/rustc_span/src/symbol.rs17
8 files changed, 148 insertions, 73 deletions
diff --git a/compiler/rustc_span/Cargo.toml b/compiler/rustc_span/Cargo.toml
index ae81d95e2..a7c7575f3 100644
--- a/compiler/rustc_span/Cargo.toml
+++ b/compiler/rustc_span/Cargo.toml
@@ -18,3 +18,4 @@ tracing = "0.1"
sha1 = "0.10.0"
sha2 = "0.10.1"
md5 = { package = "md-5", version = "0.10.0" }
+indexmap = { version = "1.9.3" }
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 162c15574..b2c58caff 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -1,13 +1,17 @@
use crate::{HashStableContext, Symbol};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
+use rustc_data_structures::unhash::Unhasher;
use rustc_data_structures::AtomicRef;
use rustc_index::vec::Idx;
use rustc_macros::HashStable_Generic;
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use std::borrow::Borrow;
use std::fmt;
-use std::hash::{Hash, Hasher};
+use std::hash::{BuildHasherDefault, Hash, Hasher};
+
+pub type StableCrateIdMap =
+ indexmap::IndexMap<StableCrateId, CrateNum, BuildHasherDefault<Unhasher>>;
rustc_index::newtype_index! {
#[custom_encodable]
diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs
index 89f0386e3..259f42386 100644
--- a/compiler/rustc_span/src/edit_distance.rs
+++ b/compiler/rustc_span/src/edit_distance.rs
@@ -174,10 +174,10 @@ pub fn find_best_match_for_name(
fn find_best_match_for_name_impl(
use_substring_score: bool,
candidates: &[Symbol],
- lookup: Symbol,
+ lookup_symbol: Symbol,
dist: Option<usize>,
) -> Option<Symbol> {
- let lookup = lookup.as_str();
+ let lookup = lookup_symbol.as_str();
let lookup_uppercase = lookup.to_uppercase();
// Priority of matches:
@@ -190,6 +190,8 @@ fn find_best_match_for_name_impl(
let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3);
let mut best = None;
+ // store the candidates with the same distance, only for `use_substring_score` current.
+ let mut next_candidates = vec![];
for c in candidates {
match if use_substring_score {
edit_distance_with_substrings(lookup, c.as_str(), dist)
@@ -198,12 +200,36 @@ fn find_best_match_for_name_impl(
} {
Some(0) => return Some(*c),
Some(d) => {
- dist = d - 1;
+ if use_substring_score {
+ if d < dist {
+ dist = d;
+ next_candidates.clear();
+ } else {
+ // `d == dist` here, we need to store the candidates with the same distance
+ // so we won't decrease the distance in the next loop.
+ }
+ next_candidates.push(*c);
+ } else {
+ dist = d - 1;
+ }
best = Some(*c);
}
None => {}
}
}
+
+ // We have a tie among several candidates, try to select the best among them ignoring substrings.
+ // For example, the candidates list `force_capture`, `capture`, and user inputted `forced_capture`,
+ // we select `force_capture` with a extra round of edit distance calculation.
+ if next_candidates.len() > 1 {
+ debug_assert!(use_substring_score);
+ best = find_best_match_for_name_impl(
+ false,
+ &next_candidates,
+ lookup_symbol,
+ Some(lookup.len()),
+ );
+ }
if best.is_some() {
return best;
}
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index dee823eef..08c441403 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -109,7 +109,7 @@ fn assert_default_hashing_controls<CTX: HashStableContext>(ctx: &CTX, msg: &str)
// This is the case for instance when building a hash for name mangling.
// Such configuration must not be used for metadata.
HashingControls { hash_spans }
- if hash_spans == !ctx.unstable_opts_incremental_ignore_spans() => {}
+ if hash_spans != ctx.unstable_opts_incremental_ignore_spans() => {}
other => panic!("Attempted hashing of {msg} with non-default HashingControls: {other:?}"),
}
}
@@ -880,7 +880,7 @@ impl Span {
pub fn fresh_expansion(self, expn_id: LocalExpnId) -> Span {
HygieneData::with(|data| {
self.with_ctxt(data.apply_mark(
- SyntaxContext::root(),
+ self.ctxt(),
expn_id.to_expn_id(),
Transparency::Transparent,
))
@@ -1151,6 +1151,7 @@ pub enum DesugaringKind {
Await,
ForLoop,
WhileLoop,
+ Replace,
}
impl DesugaringKind {
@@ -1166,6 +1167,7 @@ impl DesugaringKind {
DesugaringKind::OpaqueTy => "`impl Trait`",
DesugaringKind::ForLoop => "`for` loop",
DesugaringKind::WhileLoop => "`while` loop",
+ DesugaringKind::Replace => "drop and replace",
}
}
}
@@ -1205,7 +1207,7 @@ impl HygieneEncodeContext {
// a `SyntaxContext` that we haven't seen before
while !self.latest_ctxts.lock().is_empty() || !self.latest_expns.lock().is_empty() {
debug!(
- "encode_hygiene: Serializing a round of {:?} SyntaxContextDatas: {:?}",
+ "encode_hygiene: Serializing a round of {:?} SyntaxContextData: {:?}",
self.latest_ctxts.lock().len(),
self.latest_ctxts
);
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 873cd33f6..28a8d8fc1 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -20,6 +20,7 @@
#![feature(min_specialization)]
#![feature(rustc_attrs)]
#![feature(let_chains)]
+#![feature(round_char_boundary)]
#![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)]
@@ -87,6 +88,14 @@ pub struct SessionGlobals {
symbol_interner: symbol::Interner,
span_interner: Lock<span_encoding::SpanInterner>,
hygiene_data: Lock<hygiene::HygieneData>,
+
+ /// A reference to the source map in the `Session`. It's an `Option`
+ /// because it can't be initialized until `Session` is created, which
+ /// happens after `SessionGlobals`. `set_source_map` does the
+ /// initialization.
+ ///
+ /// This field should only be used in places where the `Session` is truly
+ /// not available, such as `<Span as Debug>::fmt`.
source_map: Lock<Option<Lrc<SourceMap>>>,
}
@@ -795,6 +804,18 @@ impl Span {
})
}
+ /// Splits a span into two composite spans around a certain position.
+ pub fn split_at(self, pos: u32) -> (Span, Span) {
+ let len = self.hi().0 - self.lo().0;
+ debug_assert!(pos <= len);
+
+ let split_pos = BytePos(self.lo().0 + pos);
+ (
+ Span::new(self.lo(), split_pos, self.ctxt(), self.parent()),
+ Span::new(split_pos, self.hi(), self.ctxt(), self.parent()),
+ )
+ }
+
/// Returns a `Span` that would enclose both `self` and `end`.
///
/// Note that this can also be used to extend the span "backwards":
@@ -1001,16 +1022,9 @@ impl<D: Decoder> Decodable<D> for Span {
}
}
-/// Calls the provided closure, using the provided `SourceMap` to format
-/// any spans that are debug-printed during the closure's execution.
-///
-/// Normally, the global `TyCtxt` is used to retrieve the `SourceMap`
-/// (see `rustc_interface::callbacks::span_debug1`). However, some parts
-/// of the compiler (e.g. `rustc_parse`) may debug-print `Span`s before
-/// a `TyCtxt` is available. In this case, we fall back to
-/// the `SourceMap` provided to this function. If that is not available,
-/// we fall back to printing the raw `Span` field values.
-pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {
+/// Insert `source_map` into the session globals for the duration of the
+/// closure's execution.
+pub fn set_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) -> T {
with_session_globals(|session_globals| {
*session_globals.source_map.borrow_mut() = Some(source_map);
});
@@ -1029,6 +1043,8 @@ pub fn with_source_map<T, F: FnOnce() -> T>(source_map: Lrc<SourceMap>, f: F) ->
impl fmt::Debug for Span {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // Use the global `SourceMap` to print the span. If that's not
+ // available, fall back to printing the raw values.
with_session_globals(|session_globals| {
if let Some(source_map) = &*session_globals.source_map.borrow() {
write!(f, "{} ({:?})", source_map.span_to_diagnostic_string(*self), self.ctxt())
@@ -1303,7 +1319,6 @@ pub struct SourceFileDiffs {
}
/// A single source in the [`SourceMap`].
-#[derive(Clone)]
pub struct SourceFile {
/// The name of the file that the source came from. Source that doesn't
/// originate from files has names between angle brackets by convention
@@ -1334,6 +1349,25 @@ pub struct SourceFile {
pub cnum: CrateNum,
}
+impl Clone for SourceFile {
+ fn clone(&self) -> Self {
+ Self {
+ name: self.name.clone(),
+ src: self.src.clone(),
+ src_hash: self.src_hash,
+ external_src: Lock::new(self.external_src.borrow().clone()),
+ start_pos: self.start_pos,
+ end_pos: self.end_pos,
+ lines: Lock::new(self.lines.borrow().clone()),
+ multibyte_chars: self.multibyte_chars.clone(),
+ non_narrow_chars: self.non_narrow_chars.clone(),
+ normalized_pos: self.normalized_pos.clone(),
+ name_hash: self.name_hash,
+ cnum: self.cnum,
+ }
+ }
+}
+
impl<S: Encoder> Encodable<S> for SourceFile {
fn encode(&self, s: &mut S) {
self.name.encode(s);
@@ -2018,13 +2052,13 @@ pub type FileLinesResult = Result<FileLines, SpanLinesError>;
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum SpanLinesError {
- DistinctSources(DistinctSources),
+ DistinctSources(Box<DistinctSources>),
}
#[derive(Clone, PartialEq, Eq, Debug)]
pub enum SpanSnippetError {
IllFormedSpan(Span),
- DistinctSources(DistinctSources),
+ DistinctSources(Box<DistinctSources>),
MalformedForSourcemap(MalformedSourceMapPositions),
SourceNotAvailable { filename: FileName },
}
diff --git a/compiler/rustc_span/src/profiling.rs b/compiler/rustc_span/src/profiling.rs
index 0ab890b9f..66e5369da 100644
--- a/compiler/rustc_span/src/profiling.rs
+++ b/compiler/rustc_span/src/profiling.rs
@@ -1,3 +1,5 @@
+use crate::source_map::SourceMap;
+
use std::borrow::Borrow;
use rustc_data_structures::profiling::EventArgRecorder;
@@ -11,25 +13,17 @@ pub trait SpannedEventArgRecorder {
///
/// Note: when self-profiling with costly event arguments, at least one argument
/// needs to be recorded. A panic will be triggered if that doesn't happen.
- fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span)
+ fn record_arg_with_span<A>(&mut self, source_map: &SourceMap, event_arg: A, span: crate::Span)
where
A: Borrow<str> + Into<String>;
}
impl SpannedEventArgRecorder for EventArgRecorder<'_> {
- fn record_arg_with_span<A>(&mut self, event_arg: A, span: crate::Span)
+ fn record_arg_with_span<A>(&mut self, source_map: &SourceMap, event_arg: A, span: crate::Span)
where
A: Borrow<str> + Into<String>,
{
self.record_arg(event_arg);
-
- let span_arg = crate::with_session_globals(|session_globals| {
- if let Some(source_map) = &*session_globals.source_map.borrow() {
- source_map.span_to_embeddable_string(span)
- } else {
- format!("{span:?}")
- }
- });
- self.record_arg(span_arg);
+ self.record_arg(source_map.span_to_embeddable_string(span));
}
}
diff --git a/compiler/rustc_span/src/source_map.rs b/compiler/rustc_span/src/source_map.rs
index 2e339a9d2..56573814e 100644
--- a/compiler/rustc_span/src/source_map.rs
+++ b/compiler/rustc_span/src/source_map.rs
@@ -100,6 +100,9 @@ pub trait FileLoader {
/// Read the contents of a UTF-8 file into memory.
fn read_file(&self, path: &Path) -> io::Result<String>;
+
+ /// Read the contents of a potentially non-UTF-8 file into memory.
+ fn read_binary_file(&self, path: &Path) -> io::Result<Vec<u8>>;
}
/// A FileLoader that uses std::fs to load real files.
@@ -113,6 +116,10 @@ impl FileLoader for RealFileLoader {
fn read_file(&self, path: &Path) -> io::Result<String> {
fs::read_to_string(path)
}
+
+ fn read_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> {
+ fs::read(path)
+ }
}
/// This is a [SourceFile] identifier that is used to correlate source files between
@@ -220,9 +227,7 @@ impl SourceMap {
/// Unlike `load_file`, guarantees that no normalization like BOM-removal
/// takes place.
pub fn load_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> {
- // Ideally, this should use `self.file_loader`, but it can't
- // deal with binary files yet.
- let bytes = fs::read(path)?;
+ let bytes = self.file_loader.read_binary_file(path)?;
// We need to add file to the `SourceMap`, so that it is present
// in dep-info. There's also an edge case that file might be both
@@ -443,25 +448,36 @@ impl SourceMap {
sp: Span,
filename_display_pref: FileNameDisplayPreference,
) -> String {
- if self.files.borrow().source_files.is_empty() || sp.is_dummy() {
- return "no-location".to_string();
- }
+ let (source_file, lo_line, lo_col, hi_line, hi_col) = self.span_to_location_info(sp);
+
+ let file_name = match source_file {
+ Some(sf) => sf.name.display(filename_display_pref).to_string(),
+ None => return "no-location".to_string(),
+ };
- let lo = self.lookup_char_pos(sp.lo());
- let hi = self.lookup_char_pos(sp.hi());
format!(
- "{}:{}:{}{}",
- lo.file.name.display(filename_display_pref),
- lo.line,
- lo.col.to_usize() + 1,
+ "{file_name}:{lo_line}:{lo_col}{}",
if let FileNameDisplayPreference::Short = filename_display_pref {
String::new()
} else {
- format!(": {}:{}", hi.line, hi.col.to_usize() + 1)
+ format!(": {hi_line}:{hi_col}")
}
)
}
+ pub fn span_to_location_info(
+ &self,
+ sp: Span,
+ ) -> (Option<Lrc<SourceFile>>, usize, usize, usize, usize) {
+ if self.files.borrow().source_files.is_empty() || sp.is_dummy() {
+ return (None, 0, 0, 0, 0);
+ }
+
+ let lo = self.lookup_char_pos(sp.lo());
+ let hi = self.lookup_char_pos(sp.hi());
+ (Some(lo.file), lo.line, lo.col.to_usize() + 1, hi.line, hi.col.to_usize() + 1)
+ }
+
/// Format the span location suitable for embedding in build artifacts
pub fn span_to_embeddable_string(&self, sp: Span) -> String {
self.span_to_string(sp, FileNameDisplayPreference::Remapped)
@@ -526,10 +542,10 @@ impl SourceMap {
let hi = self.lookup_char_pos(sp.hi());
trace!(?hi);
if lo.file.start_pos != hi.file.start_pos {
- return Err(SpanLinesError::DistinctSources(DistinctSources {
+ return Err(SpanLinesError::DistinctSources(Box::new(DistinctSources {
begin: (lo.file.name.clone(), lo.file.start_pos),
end: (hi.file.name.clone(), hi.file.start_pos),
- }));
+ })));
}
Ok((lo, hi))
}
@@ -587,10 +603,10 @@ impl SourceMap {
let local_end = self.lookup_byte_offset(sp.hi());
if local_begin.sf.start_pos != local_end.sf.start_pos {
- Err(SpanSnippetError::DistinctSources(DistinctSources {
+ Err(SpanSnippetError::DistinctSources(Box::new(DistinctSources {
begin: (local_begin.sf.name.clone(), local_begin.sf.start_pos),
end: (local_end.sf.name.clone(), local_end.sf.start_pos),
- }))
+ })))
} else {
self.ensure_source_file_source_present(local_begin.sf.clone());
@@ -1003,36 +1019,19 @@ impl SourceMap {
let src = local_begin.sf.external_src.borrow();
- // We need to extend the snippet to the end of the src rather than to end_index so when
- // searching forwards for boundaries we've got somewhere to search.
- let snippet = if let Some(ref src) = local_begin.sf.src {
- &src[start_index..]
+ let snippet = if let Some(src) = &local_begin.sf.src {
+ src
} else if let Some(src) = src.get_source() {
- &src[start_index..]
+ src
} else {
return 1;
};
- debug!("snippet=`{:?}`", snippet);
-
- let mut target = if forwards { end_index + 1 } else { end_index - 1 };
- debug!("initial target=`{:?}`", target);
- while !snippet.is_char_boundary(target - start_index) && target < source_len {
- target = if forwards {
- target + 1
- } else {
- match target.checked_sub(1) {
- Some(target) => target,
- None => {
- break;
- }
- }
- };
- debug!("target=`{:?}`", target);
+ if forwards {
+ (snippet.ceil_char_boundary(end_index + 1) - end_index) as u32
+ } else {
+ (end_index - snippet.floor_char_boundary(end_index - 1)) as u32
}
- debug!("final target=`{:?}`", target);
-
- if forwards { (target - end_index) as u32 } else { (end_index - target) as u32 }
}
pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 6272bf7f2..6bfae3771 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -357,6 +357,7 @@ symbols! {
always,
and,
and_then,
+ anon,
anonymous_lifetime_in_impl_trait,
any,
append_const_msg,
@@ -429,6 +430,7 @@ symbols! {
borrowck_graphviz_format,
borrowck_graphviz_postflow,
box_free,
+ box_new,
box_patterns,
box_syntax,
bpf_target_feature,
@@ -721,6 +723,8 @@ symbols! {
fn_mut,
fn_once,
fn_once_output,
+ fn_ptr_addr,
+ fn_ptr_trait,
forbid,
forget,
format,
@@ -791,13 +795,13 @@ symbols! {
i64,
i8,
ident,
- identity_future,
if_let,
if_let_guard,
if_while_or_patterns,
ignore,
impl_header_lifetime_elision,
impl_lint_pass,
+ impl_trait_in_assoc_type,
impl_trait_in_bindings,
impl_trait_in_fn_trait_return,
impl_trait_projections,
@@ -984,6 +988,7 @@ symbols! {
never_type_fallback,
new,
new_binary,
+ new_const,
new_debug,
new_display,
new_lower_exp,
@@ -1043,6 +1048,7 @@ symbols! {
optin_builtin_traits,
option,
option_env,
+ option_payload_ptr,
options,
or,
or_patterns,
@@ -1065,6 +1071,7 @@ symbols! {
panic_implementation,
panic_info,
panic_location,
+ panic_misaligned_pointer_dereference,
panic_nounwind,
panic_runtime,
panic_str,
@@ -1153,6 +1160,7 @@ symbols! {
read_enum_variant_arg,
read_struct,
read_struct_field,
+ read_via_copy,
readonly,
realloc,
reason,
@@ -1167,7 +1175,9 @@ symbols! {
reg32,
reg64,
reg_abcd,
+ reg_addr,
reg_byte,
+ reg_data,
reg_iw,
reg_nonzero,
reg_pair,
@@ -1190,6 +1200,7 @@ symbols! {
residual,
result,
return_position_impl_trait_in_trait,
+ return_type_notation,
rhs,
rintf32,
rintf64,
@@ -1197,6 +1208,8 @@ symbols! {
rlib,
rotate_left,
rotate_right,
+ roundevenf32,
+ roundevenf64,
roundf32,
roundf64,
rt,
@@ -1238,6 +1251,7 @@ symbols! {
rustc_diagnostic_macros,
rustc_dirty,
rustc_do_not_const_check,
+ rustc_doc_primitive,
rustc_dummy,
rustc_dump_env_program_clauses,
rustc_dump_program_clauses,
@@ -1486,6 +1500,7 @@ symbols! {
trait_alias,
trait_upcasting,
transmute,
+ transmute_generic_consts,
transmute_opts,
transmute_trait,
transparent,