diff --git a/Cargo.lock b/Cargo.lock index 37bbe95d63381..5d05a09f03893 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -809,9 +809,9 @@ dependencies = [ [[package]] name = "compiler_builtins" -version = "0.1.84" +version = "0.1.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989b2c1ca6e90ad06fdc69d1d1862fa28d27a977be6d92ae2fa762cf61fe0b10" +checksum = "13e81c6cd7ab79f51a0c927d22858d61ad12bd0b3865f0b13ece02a4486aeabb" dependencies = [ "cc", "rustc-std-workspace-core", @@ -4627,9 +4627,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.3" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b1fbb4dfc4eb1d390c02df47760bb19a84bb80b301ecc947ab5406394d8223e" +checksum = "a3807b5d10909833d3e9acd1eb5fb988f79376ff10fce42937de71a449c4c588" dependencies = [ "bitflags", "errno", diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index b09ddf80e2a52..7a5191b77f1d4 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -521,7 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { callee_expr, call_expr, callee_ty, - pick, + &pick, segment, ); if pick.illegal_sized_bound.is_some() { diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs index 03d0e7926de11..218c54688aa3e 100644 --- a/compiler/rustc_hir_typeck/src/method/confirm.rs +++ b/compiler/rustc_hir_typeck/src/method/confirm.rs @@ -45,7 +45,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self_expr: &'tcx hir::Expr<'tcx>, call_expr: &'tcx hir::Expr<'tcx>, unadjusted_self_ty: Ty<'tcx>, - pick: probe::Pick<'tcx>, + pick: &probe::Pick<'tcx>, segment: &hir::PathSegment<'_>, ) -> ConfirmResult<'tcx> { debug!( @@ -71,7 +71,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn confirm( &mut self, unadjusted_self_ty: Ty<'tcx>, - pick: probe::Pick<'tcx>, + pick: &probe::Pick<'tcx>, segment: &hir::PathSegment<'_>, ) -> ConfirmResult<'tcx> { // Adjust the self expression the user provided and obtain the adjusted type. diff --git a/compiler/rustc_hir_typeck/src/method/mod.rs b/compiler/rustc_hir_typeck/src/method/mod.rs index a2ca5c3b7b749..b15c086ffad57 100644 --- a/compiler/rustc_hir_typeck/src/method/mod.rs +++ b/compiler/rustc_hir_typeck/src/method/mod.rs @@ -192,8 +192,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.tcx.check_stability(pick.item.def_id, Some(call_expr.hir_id), span, None); - let result = - self.confirm_method(span, self_expr, call_expr, self_ty, pick.clone(), segment); + let result = self.confirm_method(span, self_expr, call_expr, self_ty, &pick, segment); debug!("result = {:?}", result); if let Some(span) = result.illegal_sized_bound { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index ae299cc9d1370..070359e71becc 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -38,9 +38,9 @@ use rustc_trait_selection::traits::query::method_autoderef::{ use rustc_trait_selection::traits::query::CanonicalTyGoal; use rustc_trait_selection::traits::NormalizeExt; use rustc_trait_selection::traits::{self, ObligationCause}; +use std::cell::RefCell; use std::cmp::max; use std::iter; -use std::mem; use std::ops::Deref; use smallvec::{smallvec, SmallVec}; @@ -62,28 +62,29 @@ struct ProbeContext<'a, 'tcx> { /// This is the OriginalQueryValues for the steps queries /// that are answered in steps. - orig_steps_var_values: OriginalQueryValues<'tcx>, + orig_steps_var_values: &'a OriginalQueryValues<'tcx>, steps: &'tcx [CandidateStep<'tcx>], inherent_candidates: Vec>, extension_candidates: Vec>, impl_dups: FxHashSet, - /// Collects near misses when the candidate functions are missing a `self` keyword and is only - /// used for error reporting - static_candidates: Vec, - /// When probing for names, include names that are close to the - /// requested name (by Levensthein distance) + /// requested name (by Levenshtein distance) allow_similar_names: bool, /// Some(candidate) if there is a private candidate private_candidate: Option<(DefKind, DefId)>, + /// Collects near misses when the candidate functions are missing a `self` keyword and is only + /// used for error reporting + static_candidates: RefCell>, + /// Collects near misses when trait bounds for type parameters are unsatisfied and is only used /// for error reporting - unsatisfied_predicates: + unsatisfied_predicates: RefCell< Vec<(ty::Predicate<'tcx>, Option>, Option>)>, + >, scope_expr_id: hir::HirId, } @@ -334,7 +335,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { op: OP, ) -> Result> where - OP: FnOnce(ProbeContext<'a, 'tcx>) -> Result>, + OP: FnOnce(ProbeContext<'_, 'tcx>) -> Result>, { let mut orig_values = OriginalQueryValues::default(); let param_env_and_self_ty = self.canonicalize_query( @@ -445,7 +446,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { mode, method_name, return_type, - orig_values, + &orig_values, steps.steps, scope_expr_id, ); @@ -539,7 +540,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { mode: Mode, method_name: Option, return_type: Option>, - orig_steps_var_values: OriginalQueryValues<'tcx>, + orig_steps_var_values: &'a OriginalQueryValues<'tcx>, steps: &'tcx [CandidateStep<'tcx>], scope_expr_id: hir::HirId, ) -> ProbeContext<'a, 'tcx> { @@ -554,10 +555,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { impl_dups: FxHashSet::default(), orig_steps_var_values, steps, - static_candidates: Vec::new(), allow_similar_names: false, private_candidate: None, - unsatisfied_predicates: Vec::new(), + static_candidates: RefCell::new(Vec::new()), + unsatisfied_predicates: RefCell::new(Vec::new()), scope_expr_id, } } @@ -566,8 +567,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.inherent_candidates.clear(); self.extension_candidates.clear(); self.impl_dups.clear(); - self.static_candidates.clear(); self.private_candidate = None; + self.static_candidates.borrow_mut().clear(); + self.unsatisfied_predicates.borrow_mut().clear(); } /////////////////////////////////////////////////////////////////////////// @@ -1003,9 +1005,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { debug!("pick: actual search failed, assemble diagnostics"); - let static_candidates = mem::take(&mut self.static_candidates); + let static_candidates = std::mem::take(self.static_candidates.get_mut()); let private_candidate = self.private_candidate.take(); - let unsatisfied_predicates = mem::take(&mut self.unsatisfied_predicates); + let unsatisfied_predicates = std::mem::take(self.unsatisfied_predicates.get_mut()); // things failed, so lets look at all traits, for diagnostic purposes now: self.reset(); @@ -1050,7 +1052,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { })) } - fn pick_core(&mut self) -> Option> { + fn pick_core(&self) -> Option> { let pick = self.pick_all_method(Some(&mut vec![])); // In this case unstable picking is done by `pick_method`. @@ -1065,11 +1067,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } fn pick_all_method( - &mut self, + &self, mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, ) -> Option> { - let steps = self.steps.clone(); - steps + self.steps .iter() .filter(|step| { debug!("pick_all_method: step={:?}", step); @@ -1123,7 +1124,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// to transparently pass `&mut` pointers, in particular, without consuming /// them for their entire lifetime. fn pick_by_value_method( - &mut self, + &self, step: &CandidateStep<'tcx>, self_ty: Ty<'tcx>, unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, @@ -1151,7 +1152,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } fn pick_autorefd_method( - &mut self, + &self, step: &CandidateStep<'tcx>, self_ty: Ty<'tcx>, mutbl: hir::Mutability, @@ -1177,7 +1178,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// special case for this is because going from `*mut T` to `*const T` with autoderefs and /// autorefs would require dereferencing the pointer, which is not safe. fn pick_const_ptr_method( - &mut self, + &self, step: &CandidateStep<'tcx>, self_ty: Ty<'tcx>, unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, @@ -1202,7 +1203,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { }) } - fn pick_method_with_unstable(&mut self, self_ty: Ty<'tcx>) -> Option> { + fn pick_method_with_unstable(&self, self_ty: Ty<'tcx>) -> Option> { debug!("pick_method_with_unstable(self_ty={})", self.ty_to_string(self_ty)); let mut possibly_unsatisfied_predicates = Vec::new(); @@ -1213,7 +1214,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { debug!("searching {} candidates", kind); let res = self.consider_candidates( self_ty, - candidates.iter(), + candidates, &mut possibly_unsatisfied_predicates, Some(&mut vec![]), ); @@ -1222,21 +1223,27 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } } - debug!("searching unstable candidates"); - let res = self.consider_candidates( - self_ty, - self.inherent_candidates.iter().chain(&self.extension_candidates), - &mut possibly_unsatisfied_predicates, - None, - ); - if res.is_none() { - self.unsatisfied_predicates.extend(possibly_unsatisfied_predicates); + for (kind, candidates) in + &[("inherent", &self.inherent_candidates), ("extension", &self.extension_candidates)] + { + debug!("searching unstable {kind} candidates"); + let res = self.consider_candidates( + self_ty, + candidates, + &mut possibly_unsatisfied_predicates, + None, + ); + if res.is_some() { + return res; + } } - res + + self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates); + None } fn pick_method( - &mut self, + &self, self_ty: Ty<'tcx>, mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, ) -> Option> { @@ -1254,7 +1261,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { debug!("searching {} candidates", kind); let res = self.consider_candidates( self_ty, - candidates.iter(), + candidates, &mut possibly_unsatisfied_predicates, unstable_candidates.as_deref_mut(), ); @@ -1266,28 +1273,24 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // `pick_method` may be called twice for the same self_ty if no stable methods // match. Only extend once. if unstable_candidates.is_some() { - self.unsatisfied_predicates.extend(possibly_unsatisfied_predicates); + self.unsatisfied_predicates.borrow_mut().extend(possibly_unsatisfied_predicates); } None } - fn consider_candidates<'b, ProbesIter>( + fn consider_candidates( &self, self_ty: Ty<'tcx>, - probes: ProbesIter, + candidates: &[Candidate<'tcx>], possibly_unsatisfied_predicates: &mut Vec<( ty::Predicate<'tcx>, Option>, Option>, )>, mut unstable_candidates: Option<&mut Vec<(Candidate<'tcx>, Symbol)>>, - ) -> Option> - where - ProbesIter: Iterator> + Clone, - 'tcx: 'b, - { - let mut applicable_candidates: Vec<_> = probes - .clone() + ) -> Option> { + let mut applicable_candidates: Vec<_> = candidates + .iter() .map(|probe| { (probe, self.consider_probe(self_ty, probe, possibly_unsatisfied_predicates)) }) @@ -1305,11 +1308,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } if let Some(uc) = &mut unstable_candidates { - applicable_candidates.retain(|&(p, _)| { + applicable_candidates.retain(|&(candidate, _)| { if let stability::EvalResult::Deny { feature, .. } = - self.tcx.eval_stability(p.item.def_id, None, self.span, None) + self.tcx.eval_stability(candidate.item.def_id, None, self.span, None) { - uc.push((p.clone(), feature)); + uc.push((candidate.clone(), feature)); return false; } true @@ -1317,7 +1320,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } if applicable_candidates.len() > 1 { - let sources = probes.map(|p| self.candidate_source(p, self_ty)).collect(); + let sources = candidates.iter().map(|p| self.candidate_source(p, self_ty)).collect(); return Some(Err(MethodError::Ambiguity(sources))); } @@ -1701,7 +1704,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { self.mode, self.method_name, self.return_type, - self.orig_steps_var_values.clone(), + &self.orig_steps_var_values, steps, self.scope_expr_id, ); @@ -1763,8 +1766,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { // -- but this could be overcome. } - fn record_static_candidate(&mut self, source: CandidateSource) { - self.static_candidates.push(source); + fn record_static_candidate(&self, source: CandidateSource) { + self.static_candidates.borrow_mut().push(source); } #[instrument(level = "debug", skip(self))] diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index a7aefc26b97c7..29b5a468bf4c5 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -16,7 +16,7 @@ panic_unwind = { path = "../panic_unwind", optional = true } panic_abort = { path = "../panic_abort" } core = { path = "../core" } libc = { version = "0.2.138", default-features = false, features = ['rustc-dep-of-std'] } -compiler_builtins = { version = "0.1.82" } +compiler_builtins = { version = "0.1.85" } profiler_builtins = { path = "../profiler_builtins", optional = true } unwind = { path = "../unwind" } hashbrown = { version = "0.12", default-features = false, features = ['rustc-dep-of-std'] } diff --git a/library/std/src/sys/unix/locks/pthread_condvar.rs b/library/std/src/sys/unix/locks/pthread_condvar.rs index 1ddb09905db2c..6be1abc2b080a 100644 --- a/library/std/src/sys/unix/locks/pthread_condvar.rs +++ b/library/std/src/sys/unix/locks/pthread_condvar.rs @@ -2,6 +2,7 @@ use crate::cell::UnsafeCell; use crate::ptr; use crate::sync::atomic::{AtomicPtr, Ordering::Relaxed}; use crate::sys::locks::{pthread_mutex, Mutex}; +use crate::sys::time::TIMESPEC_MAX; use crate::sys_common::lazy_box::{LazyBox, LazyInit}; use crate::time::Duration; @@ -12,13 +13,6 @@ pub struct Condvar { mutex: AtomicPtr, } -const TIMESPEC_MAX: libc::timespec = - libc::timespec { tv_sec: ::MAX, tv_nsec: 1_000_000_000 - 1 }; - -fn saturating_cast_to_time_t(value: u64) -> libc::time_t { - if value > ::MAX as u64 { ::MAX } else { value as libc::time_t } -} - #[inline] fn raw(c: &Condvar) -> *mut libc::pthread_cond_t { c.inner.0.get() @@ -133,26 +127,15 @@ impl Condvar { target_os = "horizon" )))] pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { - use crate::mem; + use crate::sys::time::Timespec; let mutex = pthread_mutex::raw(mutex); self.verify(mutex); - let mut now: libc::timespec = mem::zeroed(); - let r = libc::clock_gettime(libc::CLOCK_MONOTONIC, &mut now); - assert_eq!(r, 0); - - // Nanosecond calculations can't overflow because both values are below 1e9. - let nsec = dur.subsec_nanos() + now.tv_nsec as u32; - - let sec = saturating_cast_to_time_t(dur.as_secs()) - .checked_add((nsec / 1_000_000_000) as libc::time_t) - .and_then(|s| s.checked_add(now.tv_sec)); - let nsec = nsec % 1_000_000_000; - - let timeout = - sec.map(|s| libc::timespec { tv_sec: s, tv_nsec: nsec as _ }).unwrap_or(TIMESPEC_MAX); - + let timeout = Timespec::now(libc::CLOCK_MONOTONIC) + .checked_add_duration(&dur) + .and_then(|t| t.to_timespec()) + .unwrap_or(TIMESPEC_MAX); let r = libc::pthread_cond_timedwait(raw(self), mutex, &timeout); assert!(r == libc::ETIMEDOUT || r == 0); r == 0 @@ -169,57 +152,41 @@ impl Condvar { target_os = "espidf", target_os = "horizon" ))] - pub unsafe fn wait_timeout(&self, mutex: &Mutex, mut dur: Duration) -> bool { + pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool { + use crate::sys::time::SystemTime; use crate::time::Instant; let mutex = pthread_mutex::raw(mutex); self.verify(mutex); - // 1000 years - let max_dur = Duration::from_secs(1000 * 365 * 86400); - - if dur > max_dur { - // OSX implementation of `pthread_cond_timedwait` is buggy - // with super long durations. When duration is greater than - // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` - // in macOS Sierra return error 316. - // - // This program demonstrates the issue: - // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c - // - // To work around this issue, and possible bugs of other OSes, timeout - // is clamped to 1000 years, which is allowable per the API of `wait_timeout` - // because of spurious wakeups. - - dur = max_dur; - } - - // First, figure out what time it currently is, in both system and - // stable time. pthread_cond_timedwait uses system time, but we want to - // report timeout based on stable time. - let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 }; - let stable_now = Instant::now(); - let r = libc::gettimeofday(&mut sys_now, ptr::null_mut()); - assert_eq!(r, 0, "unexpected error: {:?}", crate::io::Error::last_os_error()); - - let nsec = dur.subsec_nanos() as libc::c_long + (sys_now.tv_usec * 1000) as libc::c_long; - let extra = (nsec / 1_000_000_000) as libc::time_t; - let nsec = nsec % 1_000_000_000; - let seconds = saturating_cast_to_time_t(dur.as_secs()); - - let timeout = sys_now - .tv_sec - .checked_add(extra) - .and_then(|s| s.checked_add(seconds)) - .map(|s| libc::timespec { tv_sec: s, tv_nsec: nsec }) + // OSX implementation of `pthread_cond_timedwait` is buggy + // with super long durations. When duration is greater than + // 0x100_0000_0000_0000 seconds, `pthread_cond_timedwait` + // in macOS Sierra returns error 316. + // + // This program demonstrates the issue: + // https://gist.github.com/stepancheg/198db4623a20aad2ad7cddb8fda4a63c + // + // To work around this issue, and possible bugs of other OSes, timeout + // is clamped to 1000 years, which is allowable per the API of `wait_timeout` + // because of spurious wakeups. + let dur = Duration::min(dur, Duration::from_secs(1000 * 365 * 86400)); + + // pthread_cond_timedwait uses system time, but we want to report timeout + // based on stable time. + let now = Instant::now(); + + let timeout = SystemTime::now() + .t + .checked_add_duration(&dur) + .and_then(|t| t.to_timespec()) .unwrap_or(TIMESPEC_MAX); - // And wait! let r = libc::pthread_cond_timedwait(raw(self), mutex, &timeout); debug_assert!(r == libc::ETIMEDOUT || r == 0); // ETIMEDOUT is not a totally reliable method of determining timeout due // to clock shifts, so do the check ourselves - stable_now.elapsed() < dur + now.elapsed() < dur } } diff --git a/library/std/src/sys/unix/thread_parker/pthread.rs b/library/std/src/sys/unix/thread_parker/pthread.rs index 3dfc0026ed1a4..c400c7715676f 100644 --- a/library/std/src/sys/unix/thread_parker/pthread.rs +++ b/library/std/src/sys/unix/thread_parker/pthread.rs @@ -6,6 +6,7 @@ use crate::pin::Pin; use crate::ptr::addr_of_mut; use crate::sync::atomic::AtomicUsize; use crate::sync::atomic::Ordering::SeqCst; +use crate::sys::time::TIMESPEC_MAX; use crate::time::Duration; const EMPTY: usize = 0; @@ -32,9 +33,6 @@ unsafe fn wait(cond: *mut libc::pthread_cond_t, lock: *mut libc::pthread_mutex_t debug_assert_eq!(r, 0); } -const TIMESPEC_MAX: libc::timespec = - libc::timespec { tv_sec: ::MAX, tv_nsec: 1_000_000_000 - 1 }; - unsafe fn wait_timeout( cond: *mut libc::pthread_cond_t, lock: *mut libc::pthread_mutex_t, diff --git a/library/std/src/sys/unix/time.rs b/library/std/src/sys/unix/time.rs index d5abd9b581c65..2daad981b73e9 100644 --- a/library/std/src/sys/unix/time.rs +++ b/library/std/src/sys/unix/time.rs @@ -5,6 +5,9 @@ pub use self::inner::Instant; const NSEC_PER_SEC: u64 = 1_000_000_000; pub const UNIX_EPOCH: SystemTime = SystemTime { t: Timespec::zero() }; +#[allow(dead_code)] // Used for pthread condvar timeouts +pub const TIMESPEC_MAX: libc::timespec = + libc::timespec { tv_sec: ::MAX, tv_nsec: 1_000_000_000 - 1 }; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index e0be4c432f168..24b033cc0dc5e 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -747,19 +747,9 @@ impl Step for RustAnalyzerProcMacroSrv { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - let builder = run.builder; - // Allow building `rust-analyzer-proc-macro-srv` both as part of the `rust-analyzer` and as a stand-alone tool. run.path("src/tools/rust-analyzer") .path("src/tools/rust-analyzer/crates/proc-macro-srv-cli") - .default_condition( - builder.config.extended - && builder.config.tools.as_ref().map_or(true, |tools| { - tools.iter().any(|tool| { - tool == "rust-analyzer" || tool == "rust-analyzer-proc-macro-srv" - }) - }), - ) } fn make_run(run: RunConfig<'_>) { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index cd8c8c463b1ab..8a9e6caf611ba 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -21,15 +21,15 @@ use rustc_span::{BytePos, Span, DUMMY_SP}; use super::format::{self, Buffer}; /// This type is needed in case we want to render links on items to allow to go to their definition. -pub(crate) struct HrefContext<'a, 'b, 'c> { - pub(crate) context: &'a Context<'b>, +pub(crate) struct HrefContext<'a, 'tcx> { + pub(crate) context: &'a Context<'tcx>, /// This span contains the current file we're going through. pub(crate) file_span: Span, /// This field is used to know "how far" from the top of the directory we are to link to either /// documentation pages or other source pages. - pub(crate) root_path: &'c str, + pub(crate) root_path: &'a str, /// This field is used to calculate precise local URLs. - pub(crate) current_href: &'c str, + pub(crate) current_href: String, } /// Decorations are represented as a map from CSS class to vector of character ranges. @@ -70,7 +70,7 @@ pub(crate) fn render_source_with_highlighting( src: &str, out: &mut Buffer, line_numbers: Buffer, - href_context: HrefContext<'_, '_, '_>, + href_context: HrefContext<'_, '_>, decoration_info: DecorationInfo, extra: Option<&str>, ) { @@ -137,7 +137,7 @@ fn can_merge(class1: Option, class2: Option, text: &str) -> bool { /// This type is used as a conveniency to prevent having to pass all its fields as arguments into /// the various functions (which became its methods). -struct TokenHandler<'a, 'b, 'c, 'd, 'e> { +struct TokenHandler<'a, 'tcx> { out: &'a mut Buffer, /// It contains the closing tag and the associated `Class`. closing_tags: Vec<(&'static str, Class)>, @@ -149,11 +149,11 @@ struct TokenHandler<'a, 'b, 'c, 'd, 'e> { current_class: Option, /// We need to keep the `Class` for each element because it could contain a `Span` which is /// used to generate links. - pending_elems: Vec<(&'b str, Option)>, - href_context: Option>, + pending_elems: Vec<(&'a str, Option)>, + href_context: Option>, } -impl<'a, 'b, 'c, 'd, 'e> TokenHandler<'a, 'b, 'c, 'd, 'e> { +impl<'a, 'tcx> TokenHandler<'a, 'tcx> { fn handle_exit_span(&mut self) { // We can't get the last `closing_tags` element using `pop()` because `closing_tags` is // being used in `write_pending_elems`. @@ -205,7 +205,7 @@ impl<'a, 'b, 'c, 'd, 'e> TokenHandler<'a, 'b, 'c, 'd, 'e> { } } -impl<'a, 'b, 'c, 'd, 'e> Drop for TokenHandler<'a, 'b, 'c, 'd, 'e> { +impl<'a, 'tcx> Drop for TokenHandler<'a, 'tcx> { /// When leaving, we need to flush all pending data to not have missing content. fn drop(&mut self) { if self.pending_exit_span.is_some() { @@ -230,7 +230,7 @@ impl<'a, 'b, 'c, 'd, 'e> Drop for TokenHandler<'a, 'b, 'c, 'd, 'e> { fn write_code( out: &mut Buffer, src: &str, - href_context: Option>, + href_context: Option>, decoration_info: Option, ) { // This replace allows to fix how the code source with DOS backline characters is displayed. @@ -514,18 +514,18 @@ impl Decorations { /// Processes program tokens, classifying strings of text by highlighting /// category (`Class`). -struct Classifier<'a> { - tokens: PeekIter<'a>, +struct Classifier<'src> { + tokens: PeekIter<'src>, in_attribute: bool, in_macro: bool, in_macro_nonterminal: bool, byte_pos: u32, file_span: Span, - src: &'a str, + src: &'src str, decorations: Option, } -impl<'a> Classifier<'a> { +impl<'src> Classifier<'src> { /// Takes as argument the source code to HTML-ify, the rust edition to use and the source code /// file span which will be used later on by the `span_correspondance_map`. fn new(src: &str, file_span: Span, decoration_info: Option) -> Classifier<'_> { @@ -603,7 +603,7 @@ impl<'a> Classifier<'a> { /// /// It returns the token's kind, the token as a string and its byte position in the source /// string. - fn next(&mut self) -> Option<(TokenKind, &'a str, u32)> { + fn next(&mut self) -> Option<(TokenKind, &'src str, u32)> { if let Some((kind, text)) = self.tokens.next() { let before = self.byte_pos; self.byte_pos += text.len() as u32; @@ -618,7 +618,7 @@ impl<'a> Classifier<'a> { /// The general structure for this method is to iterate over each token, /// possibly giving it an HTML span with a class specifying what flavor of /// token is used. - fn highlight(mut self, sink: &mut dyn FnMut(Highlight<'a>)) { + fn highlight(mut self, sink: &mut dyn FnMut(Highlight<'src>)) { loop { if let Some(decs) = self.decorations.as_mut() { let byte_pos = self.byte_pos; @@ -666,8 +666,8 @@ impl<'a> Classifier<'a> { fn advance( &mut self, token: TokenKind, - text: &'a str, - sink: &mut dyn FnMut(Highlight<'a>), + text: &'src str, + sink: &mut dyn FnMut(Highlight<'src>), before: u32, ) { let lookahead = self.peek(); @@ -881,7 +881,7 @@ impl<'a> Classifier<'a> { fn enter_span( out: &mut Buffer, klass: Class, - href_context: &Option>, + href_context: &Option>, ) -> &'static str { string_without_closing_tag(out, "", Some(klass), href_context, true).expect( "internal error: enter_span was called with Some(klass) but did not return a \ @@ -914,7 +914,7 @@ fn string( out: &mut Buffer, text: T, klass: Option, - href_context: &Option>, + href_context: &Option>, open_tag: bool, ) { if let Some(closing_tag) = string_without_closing_tag(out, text, klass, href_context, open_tag) @@ -936,7 +936,7 @@ fn string_without_closing_tag( out: &mut Buffer, text: T, klass: Option, - href_context: &Option>, + href_context: &Option>, open_tag: bool, ) -> Option<&'static str> { let Some(klass) = klass @@ -985,7 +985,7 @@ fn string_without_closing_tag( // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338 match href { LinkFromSrc::Local(span) => { - context.href_from_span_relative(*span, href_context.current_href) + context.href_from_span_relative(*span, &href_context.current_href) } LinkFromSrc::External(def_id) => { format::href_with_root_path(*def_id, context, Some(href_context.root_path)) diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index 54e296959b0ec..e639fadeb9673 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -276,7 +276,7 @@ pub(crate) fn print_src( let mut line_numbers = Buffer::empty_from(buf); let extra; line_numbers.write_str("
");
-    let current_href = &context
+    let current_href = context
         .href_from_span(clean::Span::new(file_span), false)
         .expect("only local crates should have sources emitted");
     match source_context {
diff --git a/triagebot.toml b/triagebot.toml
index 49945e5c533cb..19e8334fc1aa3 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -469,6 +469,7 @@ compiler-team-contributors = [
     "@jackh726",
     "@fee1-dead",
     "@TaKO8Ki",
+    "@Nilstrieb",
 ]
 compiler = [
     "compiler-team",