mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-13 12:36:47 +00:00
Auto merge of #97444 - compiler-errors:rollup-2gvdav6, r=compiler-errors
Rollup of 3 pull requests Successful merges: - #96051 (Use rounding in float to Duration conversion methods) - #97066 (rustdoc: Remove `ItemFragment(Kind)`) - #97436 (Update `triagebot.toml` for macos ping group) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
9a42c6509d
@ -730,9 +730,9 @@ impl Duration {
|
||||
/// // subnormal float
|
||||
/// let res = Duration::from_secs_f64(f64::from_bits(1));
|
||||
/// assert_eq!(res, Duration::new(0, 0));
|
||||
/// // conversion uses truncation, not rounding
|
||||
/// // conversion uses rounding
|
||||
/// let res = Duration::from_secs_f64(0.999e-9);
|
||||
/// assert_eq!(res, Duration::new(0, 0));
|
||||
/// assert_eq!(res, Duration::new(0, 1));
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[must_use]
|
||||
@ -760,17 +760,17 @@ impl Duration {
|
||||
/// let res = Duration::from_secs_f32(1e-20);
|
||||
/// assert_eq!(res, Duration::new(0, 0));
|
||||
/// let res = Duration::from_secs_f32(4.2e-7);
|
||||
/// assert_eq!(res, Duration::new(0, 419));
|
||||
/// assert_eq!(res, Duration::new(0, 420));
|
||||
/// let res = Duration::from_secs_f32(2.7);
|
||||
/// assert_eq!(res, Duration::new(2, 700_000_047));
|
||||
/// assert_eq!(res, Duration::new(2, 700_000_048));
|
||||
/// let res = Duration::from_secs_f32(3e10);
|
||||
/// assert_eq!(res, Duration::new(30_000_001_024, 0));
|
||||
/// // subnormal float
|
||||
/// let res = Duration::from_secs_f32(f32::from_bits(1));
|
||||
/// assert_eq!(res, Duration::new(0, 0));
|
||||
/// // conversion uses truncation, not rounding
|
||||
/// // conversion uses rounding
|
||||
/// let res = Duration::from_secs_f32(0.999e-9);
|
||||
/// assert_eq!(res, Duration::new(0, 0));
|
||||
/// assert_eq!(res, Duration::new(0, 1));
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[must_use]
|
||||
@ -815,7 +815,7 @@ impl Duration {
|
||||
/// use std::time::Duration;
|
||||
///
|
||||
/// let dur = Duration::new(2, 700_000_000);
|
||||
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640));
|
||||
/// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_641));
|
||||
/// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847800, 0));
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
@ -838,8 +838,7 @@ impl Duration {
|
||||
///
|
||||
/// let dur = Duration::new(2, 700_000_000);
|
||||
/// assert_eq!(dur.div_f64(3.14), Duration::new(0, 859_872_611));
|
||||
/// // note that truncation is used, not rounding
|
||||
/// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_598));
|
||||
/// assert_eq!(dur.div_f64(3.14e5), Duration::new(0, 8_599));
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
@ -862,9 +861,8 @@ impl Duration {
|
||||
/// let dur = Duration::new(2, 700_000_000);
|
||||
/// // note that due to rounding errors result is slightly
|
||||
/// // different from 0.859_872_611
|
||||
/// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_579));
|
||||
/// // note that truncation is used, not rounding
|
||||
/// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598));
|
||||
/// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_580));
|
||||
/// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_599));
|
||||
/// ```
|
||||
#[stable(feature = "duration_float", since = "1.38.0")]
|
||||
#[must_use = "this returns the result of the operation, \
|
||||
@ -1272,19 +1270,53 @@ macro_rules! try_from_secs {
|
||||
let mant = (bits & MANT_MASK) | (MANT_MASK + 1);
|
||||
let exp = ((bits >> $mant_bits) & EXP_MASK) as i16 + MIN_EXP;
|
||||
|
||||
let (secs, nanos) = if exp < -30 {
|
||||
// the input represents less than 1ns.
|
||||
let (secs, nanos) = if exp < -31 {
|
||||
// the input represents less than 1ns and can not be rounded to it
|
||||
(0u64, 0u32)
|
||||
} else if exp < 0 {
|
||||
// the input is less than 1 second
|
||||
let t = <$double_ty>::from(mant) << ($offset + exp);
|
||||
let nanos = (u128::from(NANOS_PER_SEC) * u128::from(t)) >> ($mant_bits + $offset);
|
||||
(0, nanos as u32)
|
||||
let nanos_offset = $mant_bits + $offset;
|
||||
let nanos_tmp = u128::from(NANOS_PER_SEC) * u128::from(t);
|
||||
let nanos = (nanos_tmp >> nanos_offset) as u32;
|
||||
|
||||
let rem_mask = (1 << nanos_offset) - 1;
|
||||
let rem_msb_mask = 1 << (nanos_offset - 1);
|
||||
let rem = nanos_tmp & rem_mask;
|
||||
let is_tie = rem == rem_msb_mask;
|
||||
let is_even = (nanos & 1) == 0;
|
||||
let rem_msb = nanos_tmp & rem_msb_mask == 0;
|
||||
let add_ns = !(rem_msb || (is_even && is_tie));
|
||||
|
||||
// f32 does not have enough presicion to trigger the second branch
|
||||
// since it can not represent numbers between 0.999_999_940_395 and 1.0.
|
||||
let nanos = nanos + add_ns as u32;
|
||||
if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) { (0, nanos) } else { (1, 0) }
|
||||
} else if exp < $mant_bits {
|
||||
let secs = mant >> ($mant_bits - exp);
|
||||
let secs = u64::from(mant >> ($mant_bits - exp));
|
||||
let t = <$double_ty>::from((mant << exp) & MANT_MASK);
|
||||
let nanos = (<$double_ty>::from(NANOS_PER_SEC) * t) >> $mant_bits;
|
||||
(u64::from(secs), nanos as u32)
|
||||
let nanos_offset = $mant_bits;
|
||||
let nanos_tmp = <$double_ty>::from(NANOS_PER_SEC) * t;
|
||||
let nanos = (nanos_tmp >> nanos_offset) as u32;
|
||||
|
||||
let rem_mask = (1 << nanos_offset) - 1;
|
||||
let rem_msb_mask = 1 << (nanos_offset - 1);
|
||||
let rem = nanos_tmp & rem_mask;
|
||||
let is_tie = rem == rem_msb_mask;
|
||||
let is_even = (nanos & 1) == 0;
|
||||
let rem_msb = nanos_tmp & rem_msb_mask == 0;
|
||||
let add_ns = !(rem_msb || (is_even && is_tie));
|
||||
|
||||
// f32 does not have enough presicion to trigger the second branch.
|
||||
// For example, it can not represent numbers between 1.999_999_880...
|
||||
// and 2.0. Bigger values result in even smaller presicion of the
|
||||
// fractional part.
|
||||
let nanos = nanos + add_ns as u32;
|
||||
if ($mant_bits == 23) || (nanos != NANOS_PER_SEC) {
|
||||
(secs, nanos)
|
||||
} else {
|
||||
(secs + 1, 0)
|
||||
}
|
||||
} else if exp < 64 {
|
||||
// the input has no fractional part
|
||||
let secs = u64::from(mant) << (exp - $mant_bits);
|
||||
@ -1315,17 +1347,14 @@ impl Duration {
|
||||
/// let res = Duration::try_from_secs_f32(1e-20);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||
/// let res = Duration::try_from_secs_f32(4.2e-7);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 419)));
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 420)));
|
||||
/// let res = Duration::try_from_secs_f32(2.7);
|
||||
/// assert_eq!(res, Ok(Duration::new(2, 700_000_047)));
|
||||
/// assert_eq!(res, Ok(Duration::new(2, 700_000_048)));
|
||||
/// let res = Duration::try_from_secs_f32(3e10);
|
||||
/// assert_eq!(res, Ok(Duration::new(30_000_001_024, 0)));
|
||||
/// // subnormal float:
|
||||
/// let res = Duration::try_from_secs_f32(f32::from_bits(1));
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||
/// // conversion uses truncation, not rounding
|
||||
/// let res = Duration::try_from_secs_f32(0.999e-9);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||
///
|
||||
/// let res = Duration::try_from_secs_f32(-5.0);
|
||||
/// assert!(res.is_err());
|
||||
@ -1333,6 +1362,30 @@ impl Duration {
|
||||
/// assert!(res.is_err());
|
||||
/// let res = Duration::try_from_secs_f32(2e19);
|
||||
/// assert!(res.is_err());
|
||||
///
|
||||
/// // the conversion uses rounding with tie resolution to even
|
||||
/// let res = Duration::try_from_secs_f32(0.999e-9);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 1)));
|
||||
///
|
||||
/// // this float represents exactly 976562.5e-9
|
||||
/// let val = f32::from_bits(0x3A80_0000);
|
||||
/// let res = Duration::try_from_secs_f32(val);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 976_562)));
|
||||
///
|
||||
/// // this float represents exactly 2929687.5e-9
|
||||
/// let val = f32::from_bits(0x3B40_0000);
|
||||
/// let res = Duration::try_from_secs_f32(val);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 2_929_688)));
|
||||
///
|
||||
/// // this float represents exactly 1.000_976_562_5
|
||||
/// let val = f32::from_bits(0x3F802000);
|
||||
/// let res = Duration::try_from_secs_f32(val);
|
||||
/// assert_eq!(res, Ok(Duration::new(1, 976_562)));
|
||||
///
|
||||
/// // this float represents exactly 1.002_929_687_5
|
||||
/// let val = f32::from_bits(0x3F806000);
|
||||
/// let res = Duration::try_from_secs_f32(val);
|
||||
/// assert_eq!(res, Ok(Duration::new(1, 2_929_688)));
|
||||
/// ```
|
||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||
#[inline]
|
||||
@ -1372,9 +1425,6 @@ impl Duration {
|
||||
/// // subnormal float
|
||||
/// let res = Duration::try_from_secs_f64(f64::from_bits(1));
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||
/// // conversion uses truncation, not rounding
|
||||
/// let res = Duration::try_from_secs_f32(0.999e-9);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 0)));
|
||||
///
|
||||
/// let res = Duration::try_from_secs_f64(-5.0);
|
||||
/// assert!(res.is_err());
|
||||
@ -1382,6 +1432,38 @@ impl Duration {
|
||||
/// assert!(res.is_err());
|
||||
/// let res = Duration::try_from_secs_f64(2e19);
|
||||
/// assert!(res.is_err());
|
||||
///
|
||||
/// // the conversion uses rounding with tie resolution to even
|
||||
/// let res = Duration::try_from_secs_f64(0.999e-9);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 1)));
|
||||
/// let res = Duration::try_from_secs_f64(0.999_999_999_499);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 999_999_999)));
|
||||
/// let res = Duration::try_from_secs_f64(0.999_999_999_501);
|
||||
/// assert_eq!(res, Ok(Duration::new(1, 0)));
|
||||
/// let res = Duration::try_from_secs_f64(42.999_999_999_499);
|
||||
/// assert_eq!(res, Ok(Duration::new(42, 999_999_999)));
|
||||
/// let res = Duration::try_from_secs_f64(42.999_999_999_501);
|
||||
/// assert_eq!(res, Ok(Duration::new(43, 0)));
|
||||
///
|
||||
/// // this float represents exactly 976562.5e-9
|
||||
/// let val = f64::from_bits(0x3F50_0000_0000_0000);
|
||||
/// let res = Duration::try_from_secs_f64(val);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 976_562)));
|
||||
///
|
||||
/// // this float represents exactly 2929687.5e-9
|
||||
/// let val = f64::from_bits(0x3F68_0000_0000_0000);
|
||||
/// let res = Duration::try_from_secs_f64(val);
|
||||
/// assert_eq!(res, Ok(Duration::new(0, 2_929_688)));
|
||||
///
|
||||
/// // this float represents exactly 1.000_976_562_5
|
||||
/// let val = f64::from_bits(0x3FF0_0400_0000_0000);
|
||||
/// let res = Duration::try_from_secs_f64(val);
|
||||
/// assert_eq!(res, Ok(Duration::new(1, 976_562)));
|
||||
///
|
||||
/// // this float represents exactly 1.002_929_687_5
|
||||
/// let val = f64::from_bits(0x3_FF00_C000_0000_000);
|
||||
/// let res = Duration::try_from_secs_f64(val);
|
||||
/// assert_eq!(res, Ok(Duration::new(1, 2_929_688)));
|
||||
/// ```
|
||||
#[unstable(feature = "duration_checked_float", issue = "83400")]
|
||||
#[inline]
|
||||
|
@ -525,7 +525,7 @@ impl Item {
|
||||
if let Ok((mut href, ..)) = href(*did, cx) {
|
||||
debug!(?href);
|
||||
if let Some(ref fragment) = *fragment {
|
||||
fragment.render(&mut href, cx.tcx()).unwrap()
|
||||
fragment.render(&mut href, cx.tcx())
|
||||
}
|
||||
Some(RenderedLink {
|
||||
original_text: s.clone(),
|
||||
|
@ -20,7 +20,6 @@ use rustc_span::BytePos;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::Write;
|
||||
use std::mem;
|
||||
use std::ops::Range;
|
||||
|
||||
@ -220,80 +219,43 @@ enum MalformedGenerics {
|
||||
|
||||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub(crate) enum UrlFragment {
|
||||
Item(ItemFragment),
|
||||
Item(DefId),
|
||||
UserWritten(String),
|
||||
}
|
||||
|
||||
impl UrlFragment {
|
||||
/// Render the fragment, including the leading `#`.
|
||||
pub(crate) fn render(&self, s: &mut String, tcx: TyCtxt<'_>) -> std::fmt::Result {
|
||||
pub(crate) fn render(&self, s: &mut String, tcx: TyCtxt<'_>) {
|
||||
s.push('#');
|
||||
match self {
|
||||
UrlFragment::Item(frag) => frag.render(s, tcx),
|
||||
UrlFragment::UserWritten(raw) => write!(s, "#{}", raw),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub(crate) struct ItemFragment(FragmentKind, DefId);
|
||||
|
||||
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub(crate) enum FragmentKind {
|
||||
Method,
|
||||
TyMethod,
|
||||
AssociatedConstant,
|
||||
AssociatedType,
|
||||
|
||||
StructField,
|
||||
Variant,
|
||||
VariantField,
|
||||
}
|
||||
|
||||
impl FragmentKind {
|
||||
fn from_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> FragmentKind {
|
||||
match tcx.def_kind(def_id) {
|
||||
DefKind::AssocFn => {
|
||||
if tcx.associated_item(def_id).defaultness.has_value() {
|
||||
FragmentKind::Method
|
||||
} else {
|
||||
FragmentKind::TyMethod
|
||||
}
|
||||
}
|
||||
DefKind::AssocConst => FragmentKind::AssociatedConstant,
|
||||
DefKind::AssocTy => FragmentKind::AssociatedType,
|
||||
DefKind::Variant => FragmentKind::Variant,
|
||||
DefKind::Field => {
|
||||
if tcx.def_kind(tcx.parent(def_id)) == DefKind::Variant {
|
||||
FragmentKind::VariantField
|
||||
} else {
|
||||
FragmentKind::StructField
|
||||
}
|
||||
}
|
||||
kind => bug!("unexpected associated item kind: {:?}", kind),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ItemFragment {
|
||||
/// Render the fragment, including the leading `#`.
|
||||
pub(crate) fn render(&self, s: &mut String, tcx: TyCtxt<'_>) -> std::fmt::Result {
|
||||
write!(s, "#")?;
|
||||
match *self {
|
||||
ItemFragment(kind, def_id) => {
|
||||
let name = tcx.item_name(def_id);
|
||||
match kind {
|
||||
FragmentKind::Method => write!(s, "method.{}", name),
|
||||
FragmentKind::TyMethod => write!(s, "tymethod.{}", name),
|
||||
FragmentKind::AssociatedConstant => write!(s, "associatedconstant.{}", name),
|
||||
FragmentKind::AssociatedType => write!(s, "associatedtype.{}", name),
|
||||
FragmentKind::StructField => write!(s, "structfield.{}", name),
|
||||
FragmentKind::Variant => write!(s, "variant.{}", name),
|
||||
FragmentKind::VariantField => {
|
||||
let variant = tcx.item_name(tcx.parent(def_id));
|
||||
write!(s, "variant.{}.field.{}", variant, name)
|
||||
&UrlFragment::Item(def_id) => {
|
||||
let kind = match tcx.def_kind(def_id) {
|
||||
DefKind::AssocFn => {
|
||||
if tcx.associated_item(def_id).defaultness.has_value() {
|
||||
"method."
|
||||
} else {
|
||||
"tymethod."
|
||||
}
|
||||
}
|
||||
}
|
||||
DefKind::AssocConst => "associatedconstant.",
|
||||
DefKind::AssocTy => "associatedtype.",
|
||||
DefKind::Variant => "variant.",
|
||||
DefKind::Field => {
|
||||
let parent_id = tcx.parent(def_id);
|
||||
if tcx.def_kind(parent_id) == DefKind::Variant {
|
||||
s.push_str("variant.");
|
||||
s.push_str(tcx.item_name(parent_id).as_str());
|
||||
".field."
|
||||
} else {
|
||||
"structfield."
|
||||
}
|
||||
}
|
||||
kind => bug!("unexpected associated item kind: {:?}", kind),
|
||||
};
|
||||
s.push_str(kind);
|
||||
s.push_str(tcx.item_name(def_id).as_str());
|
||||
}
|
||||
UrlFragment::UserWritten(raw) => s.push_str(&raw),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -315,11 +277,6 @@ struct DiagnosticInfo<'a> {
|
||||
link_range: Range<usize>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Hash)]
|
||||
struct CachedLink {
|
||||
res: (Res, Option<UrlFragment>),
|
||||
}
|
||||
|
||||
struct LinkCollector<'a, 'tcx> {
|
||||
cx: &'a mut DocContext<'tcx>,
|
||||
/// A stack of modules used to decide what scope to resolve in.
|
||||
@ -329,7 +286,7 @@ struct LinkCollector<'a, 'tcx> {
|
||||
mod_ids: Vec<DefId>,
|
||||
/// Cache the resolved links so we can avoid resolving (and emitting errors for) the same link.
|
||||
/// The link will be `None` if it could not be resolved (i.e. the error was cached).
|
||||
visited_links: FxHashMap<ResolutionInfo, Option<CachedLink>>,
|
||||
visited_links: FxHashMap<ResolutionInfo, Option<(Res, Option<UrlFragment>)>>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
@ -1097,6 +1054,9 @@ impl LinkCollector<'_, '_> {
|
||||
extra_fragment: extra_fragment.clone(),
|
||||
},
|
||||
diag_info.clone(), // this struct should really be Copy, but Range is not :(
|
||||
// For reference-style links we want to report only one error so unsuccessful
|
||||
// resolutions are cached, for other links we want to report an error every
|
||||
// time so they are not cached.
|
||||
matches!(ori_link.kind, LinkType::Reference | LinkType::Shortcut),
|
||||
)?;
|
||||
|
||||
@ -1123,7 +1083,7 @@ impl LinkCollector<'_, '_> {
|
||||
|
||||
match res {
|
||||
Res::Primitive(prim) => {
|
||||
if let Some(UrlFragment::Item(ItemFragment(_, id))) = fragment {
|
||||
if let Some(UrlFragment::Item(id)) = fragment {
|
||||
// We're actually resolving an associated item of a primitive, so we need to
|
||||
// verify the disambiguator (if any) matches the type of the associated item.
|
||||
// This case should really follow the same flow as the `Res::Def` branch below,
|
||||
@ -1171,12 +1131,11 @@ impl LinkCollector<'_, '_> {
|
||||
})
|
||||
}
|
||||
Res::Def(kind, id) => {
|
||||
let (kind_for_dis, id_for_dis) =
|
||||
if let Some(UrlFragment::Item(ItemFragment(_, id))) = fragment {
|
||||
(self.cx.tcx.def_kind(id), id)
|
||||
} else {
|
||||
(kind, id)
|
||||
};
|
||||
let (kind_for_dis, id_for_dis) = if let Some(UrlFragment::Item(id)) = fragment {
|
||||
(self.cx.tcx.def_kind(id), id)
|
||||
} else {
|
||||
(kind, id)
|
||||
};
|
||||
self.verify_disambiguator(
|
||||
path_str,
|
||||
ori_link,
|
||||
@ -1294,53 +1253,33 @@ impl LinkCollector<'_, '_> {
|
||||
&mut self,
|
||||
key: ResolutionInfo,
|
||||
diag: DiagnosticInfo<'_>,
|
||||
cache_resolution_failure: bool,
|
||||
// If errors are cached then they are only reported on first ocurrence
|
||||
// which we want in some cases but not in others.
|
||||
cache_errors: bool,
|
||||
) -> Option<(Res, Option<UrlFragment>)> {
|
||||
if let Some(ref cached) = self.visited_links.get(&key) {
|
||||
match cached {
|
||||
Some(cached) => {
|
||||
return Some(cached.res.clone());
|
||||
}
|
||||
None if cache_resolution_failure => return None,
|
||||
None => {
|
||||
// Although we hit the cache and found a resolution error, this link isn't
|
||||
// supposed to cache those. Run link resolution again to emit the expected
|
||||
// resolution error.
|
||||
}
|
||||
if let Some(res) = self.visited_links.get(&key) {
|
||||
if res.is_some() || cache_errors {
|
||||
return res.clone();
|
||||
}
|
||||
}
|
||||
|
||||
let res = self.resolve_with_disambiguator(&key, diag.clone()).and_then(|(res, def_id)| {
|
||||
let fragment = match (&key.extra_fragment, def_id) {
|
||||
(Some(_), Some(def_id)) => {
|
||||
report_anchor_conflict(self.cx, diag, Res::from_def_id(self.cx.tcx, def_id));
|
||||
report_anchor_conflict(self.cx, diag, def_id);
|
||||
return None;
|
||||
}
|
||||
(Some(u_frag), None) => Some(UrlFragment::UserWritten(u_frag.clone())),
|
||||
(None, Some(def_id)) => Some(UrlFragment::Item(ItemFragment(
|
||||
FragmentKind::from_def_id(self.cx.tcx, def_id),
|
||||
def_id,
|
||||
))),
|
||||
(None, Some(def_id)) => Some(UrlFragment::Item(def_id)),
|
||||
(None, None) => None,
|
||||
};
|
||||
Some((res, fragment))
|
||||
});
|
||||
|
||||
// Cache only if resolved successfully - don't silence duplicate errors
|
||||
if let Some(res) = res {
|
||||
// Store result for the actual namespace
|
||||
self.visited_links.insert(key, Some(CachedLink { res: res.clone() }));
|
||||
|
||||
Some(res)
|
||||
} else {
|
||||
if cache_resolution_failure {
|
||||
// For reference-style links we only want to report one resolution error
|
||||
// so let's cache them as well.
|
||||
self.visited_links.insert(key, None);
|
||||
}
|
||||
|
||||
None
|
||||
if res.is_some() || cache_errors {
|
||||
self.visited_links.insert(key, res.clone());
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
/// After parsing the disambiguator, resolve the main part of the link.
|
||||
@ -1916,8 +1855,8 @@ fn report_multiple_anchors(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>) {
|
||||
anchor_failure(cx, diag_info, &msg, 1)
|
||||
}
|
||||
|
||||
fn report_anchor_conflict(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, res: Res) {
|
||||
let (link, kind) = (diag_info.ori_link, res.descr());
|
||||
fn report_anchor_conflict(cx: &DocContext<'_>, diag_info: DiagnosticInfo<'_>, def_id: DefId) {
|
||||
let (link, kind) = (diag_info.ori_link, Res::from_def_id(cx.tcx, def_id).descr());
|
||||
let msg = format!("`{link}` contains an anchor, but links to {kind}s are already anchored");
|
||||
anchor_failure(cx, diag_info, &msg, 0)
|
||||
}
|
||||
|
@ -80,6 +80,13 @@ resolved/implemented on Fuchsia. Could one of you weigh in?
|
||||
"""
|
||||
label = "O-fuchsia"
|
||||
|
||||
[ping.macos]
|
||||
message = """\
|
||||
Hey MacOS Group! This issue or PR could use some MacOS-specific guidance. Could one
|
||||
of you weigh in? Thanks <3
|
||||
"""
|
||||
label = "O-macos"
|
||||
|
||||
[prioritize]
|
||||
label = "I-prioritize"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user