summaryrefslogtreecommitdiffstats
path: root/src/librustdoc/passes/collect_intra_doc_links.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/librustdoc/passes/collect_intra_doc_links.rs')
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs222
1 files changed, 151 insertions, 71 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 0dd9e590b..7b0a7a90d 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -14,7 +14,7 @@ use rustc_hir::def::{DefKind, Namespace, PerNS};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
use rustc_hir::Mutability;
use rustc_middle::ty::{Ty, TyCtxt};
-use rustc_middle::{bug, ty};
+use rustc_middle::{bug, span_bug, ty};
use rustc_resolve::rustdoc::{has_primitive_or_keyword_docs, prepare_to_doc_link_resolution};
use rustc_resolve::rustdoc::{strip_generics_from_path, MalformedGenerics};
use rustc_session::lint::Lint;
@@ -150,7 +150,7 @@ impl TryFrom<ResolveRes> for Res {
PrimTy(prim) => Ok(Res::Primitive(PrimitiveType::from_hir(prim))),
// e.g. `#[derive]`
ToolMod | NonMacroAttr(..) | Err => Result::Err(()),
- other => bug!("unrecognized res {:?}", other),
+ other => bug!("unrecognized res {other:?}"),
}
}
}
@@ -224,7 +224,7 @@ impl UrlFragment {
"structfield."
}
}
- kind => bug!("unexpected associated item kind: {:?}", kind),
+ kind => bug!("unexpected associated item kind: {kind:?}"),
};
s.push_str(kind);
s.push_str(tcx.item_name(def_id).as_str());
@@ -279,7 +279,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
unresolved: path_str.into(),
};
- debug!("looking for enum variant {}", path_str);
+ debug!("looking for enum variant {path_str}");
let mut split = path_str.rsplitn(3, "::");
let variant_field_name = split
.next()
@@ -298,7 +298,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
let ty_res = self.resolve_path(&path, TypeNS, item_id, module_id).ok_or_else(no_res)?;
match ty_res {
- Res::Def(DefKind::Enum, did) => match tcx.type_of(did).subst_identity().kind() {
+ Res::Def(DefKind::Enum, did) => match tcx.type_of(did).instantiate_identity().kind() {
ty::Adt(def, _) if def.is_enum() => {
if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name)
&& let Some(field) = variant.fields.iter().find(|f| f.name == variant_field_name) {
@@ -402,10 +402,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
// `doc_link_resolutions` is missing a `path_str`, that means that there are valid links
// that are being missed. To fix the ICE, change
// `rustc_resolve::rustdoc::attrs_to_preprocessed_links` to cache the link.
- .unwrap_or_else(|| panic!("no resolution for {:?} {:?} {:?}", path_str, ns, module_id))
+ .unwrap_or_else(|| {
+ span_bug!(
+ self.cx.tcx.def_span(item_id),
+ "no resolution for {path_str:?} {ns:?} {module_id:?}",
+ )
+ })
.and_then(|res| res.try_into().ok())
.or_else(|| resolve_primitive(path_str, ns));
- debug!("{} resolved to {:?} in namespace {:?}", path_str, result, ns);
+ debug!("{path_str} resolved to {result:?} in namespace {ns:?}");
result
}
@@ -448,7 +453,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
// If there's no `::`, it's not an associated item.
// So we can be sure that `rustc_resolve` was accurate when it said it wasn't resolved.
.ok_or_else(|| {
- debug!("found no `::`, assuming {} was correctly not in scope", item_name);
+ debug!("found no `::`, assuming {item_name} was correctly not in scope");
UnresolvedPath {
item_id,
module_id,
@@ -493,7 +498,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
/// This is used for resolving type aliases.
fn def_id_to_res(&self, ty_id: DefId) -> Option<Res> {
use PrimitiveType::*;
- Some(match *self.cx.tcx.type_of(ty_id).subst_identity().kind() {
+ Some(match *self.cx.tcx.type_of(ty_id).instantiate_identity().kind() {
ty::Bool => Res::Primitive(Bool),
ty::Char => Res::Primitive(Char),
ty::Int(ity) => Res::Primitive(ity.into()),
@@ -587,7 +592,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
.unwrap_or(Vec::new())
}
}
- Res::Def(DefKind::TyAlias, did) => {
+ Res::Def(DefKind::TyAlias { .. }, did) => {
// Resolve the link on the type the alias points to.
// FIXME: if the associated item is defined directly on the type alias,
// it will show up on its documentation page, we should link there instead.
@@ -598,10 +603,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
def_kind @ (DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::ForeignTy),
did,
) => {
- debug!("looking for associated item named {} for item {:?}", item_name, did);
+ debug!("looking for associated item named {item_name} for item {did:?}");
// Checks if item_name is a variant of the `SomeItem` enum
if ns == TypeNS && def_kind == DefKind::Enum {
- match tcx.type_of(did).subst_identity().kind() {
+ match tcx.type_of(did).instantiate_identity().kind() {
ty::Adt(adt_def, _) => {
for variant in adt_def.variants() {
if variant.name == item_name {
@@ -635,7 +640,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
// To handle that properly resolve() would have to support
// something like [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn)
assoc_items = resolve_associated_trait_item(
- tcx.type_of(did).subst_identity(),
+ tcx.type_of(did).instantiate_identity(),
module_id,
item_name,
ns,
@@ -646,7 +651,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
.collect::<Vec<_>>();
}
- debug!("got associated item {:?}", assoc_items);
+ debug!("got associated item {assoc_items:?}");
if !assoc_items.is_empty() {
return assoc_items;
@@ -655,7 +660,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
if ns != Namespace::ValueNS {
return Vec::new();
}
- debug!("looking for fields named {} for {:?}", item_name, did);
+ debug!("looking for fields named {item_name} for {did:?}");
// FIXME: this doesn't really belong in `associated_item` (maybe `variant_field` is better?)
// NOTE: it's different from variant_field because it only resolves struct fields,
// not variant fields (2 path segments, not 3).
@@ -671,7 +676,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
// they also look like associated items (`module::Type::Variant`),
// because they are real Rust syntax (unlike the intra-doc links
// field syntax) and are handled by the compiler's resolver.
- let def = match tcx.type_of(did).subst_identity().kind() {
+ let def = match tcx.type_of(did).instantiate_identity().kind() {
ty::Adt(def, _) if !def.is_enum() => def,
_ => return Vec::new(),
};
@@ -722,7 +727,7 @@ fn resolve_associated_trait_item<'a>(
// Give precedence to inherent impls.
let traits = trait_impls_for(cx, ty, module);
let tcx = cx.tcx;
- debug!("considering traits {:?}", traits);
+ debug!("considering traits {traits:?}");
let candidates = traits
.iter()
.flat_map(|&(impl_, trait_)| {
@@ -739,7 +744,7 @@ fn resolve_associated_trait_item<'a>(
})
.collect::<Vec<_>>();
// FIXME(#74563): warn about ambiguity
- debug!("the candidates were {:?}", candidates);
+ debug!("the candidates were {candidates:?}");
candidates
}
@@ -785,10 +790,8 @@ fn trait_impls_for<'a>(
// Check if these are the same type.
let impl_type = trait_ref.skip_binder().self_ty();
trace!(
- "comparing type {} with kind {:?} against type {:?}",
- impl_type,
- impl_type.kind(),
- ty
+ "comparing type {impl_type} with kind {kind:?} against type {ty:?}",
+ kind = impl_type.kind(),
);
// Fast path: if this is a primitive simple `==` will work
// NOTE: the `match` is necessary; see #92662.
@@ -935,7 +938,7 @@ fn preprocess_link(
let path_str = match strip_generics_from_path(path_str) {
Ok(path) => path,
Err(err) => {
- debug!("link has malformed generics: {}", path_str);
+ debug!("link has malformed generics: {path_str}");
return Some(Err(PreprocessingError::MalformedGenerics(err, path_str.to_owned())));
}
};
@@ -963,6 +966,7 @@ fn preprocessed_markdown_links(s: &str) -> Vec<PreprocessedMarkdownLink> {
}
impl LinkCollector<'_, '_> {
+ #[instrument(level = "debug", skip_all)]
fn resolve_links(&mut self, item: &Item) {
if !self.cx.render_options.document_private
&& let Some(def_id) = item.item_id.as_def_id()
@@ -981,7 +985,7 @@ impl LinkCollector<'_, '_> {
if !may_have_doc_links(&doc) {
continue;
}
- debug!("combined_docs={}", doc);
+ debug!("combined_docs={doc}");
// NOTE: if there are links that start in one crate and end in another, this will not resolve them.
// This is a degenerate case and it's not supported by rustdoc.
let item_id = item_id.unwrap_or_else(|| item.item_id.expect_def_id());
@@ -990,7 +994,7 @@ impl LinkCollector<'_, '_> {
_ => find_nearest_parent_module(self.cx.tcx, item_id).unwrap(),
};
for md_link in preprocessed_markdown_links(&doc) {
- let link = self.resolve_link(item, item_id, module_id, &doc, &md_link);
+ let link = self.resolve_link(&doc, item, item_id, module_id, &md_link);
if let Some(link) = link {
self.cx.cache.intra_doc_links.entry(item.item_id).or_default().insert(link);
}
@@ -1003,13 +1007,12 @@ impl LinkCollector<'_, '_> {
/// FIXME(jynelson): this is way too many arguments
fn resolve_link(
&mut self,
+ dox: &String,
item: &Item,
item_id: DefId,
module_id: DefId,
- dox: &str,
- link: &PreprocessedMarkdownLink,
+ PreprocessedMarkdownLink(pp_link, ori_link): &PreprocessedMarkdownLink,
) -> Option<ItemLink> {
- let PreprocessedMarkdownLink(pp_link, ori_link) = link;
trace!("considering link '{}'", ori_link.link);
let diag_info = DiagnosticInfo {
@@ -1018,7 +1021,6 @@ impl LinkCollector<'_, '_> {
ori_link: &ori_link.link,
link_range: ori_link.range.clone(),
};
-
let PreprocessingInfo { path_str, disambiguator, extra_fragment, link_text } =
pp_link.as_ref().map_err(|err| err.report(self.cx, diag_info.clone())).ok()?;
let disambiguator = *disambiguator;
@@ -1036,8 +1038,24 @@ impl LinkCollector<'_, '_> {
// 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),
+ false,
)?;
+ if ori_link.display_text.is_some() {
+ self.resolve_display_text(
+ path_str,
+ ResolutionInfo {
+ item_id,
+ module_id,
+ dis: disambiguator,
+ path_str: ori_link.display_text.clone()?.into_boxed_str(),
+ extra_fragment: extra_fragment.clone(),
+ },
+ &ori_link,
+ &diag_info,
+ );
+ }
+
// Check for a primitive which might conflict with a module
// Report the ambiguity and require that the user specify which one they meant.
// FIXME: could there ever be a primitive not in the type namespace?
@@ -1124,10 +1142,10 @@ impl LinkCollector<'_, '_> {
item: &Item,
diag_info: &DiagnosticInfo<'_>,
) -> Option<()> {
- debug!("intra-doc link to {} resolved to {:?}", path_str, (kind, id));
+ debug!("intra-doc link to {path_str} resolved to {:?}", (kind, id));
// Disallow e.g. linking to enums with `struct@`
- debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator);
+ debug!("saw kind {kind:?} with disambiguator {disambiguator:?}");
match (kind, disambiguator) {
| (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const)))
// NOTE: this allows 'method' to mean both normal functions and associated functions
@@ -1168,7 +1186,7 @@ impl LinkCollector<'_, '_> {
diag_info: &DiagnosticInfo<'_>,
) {
// The resolved item did not match the disambiguator; give a better error than 'not found'
- let msg = format!("incompatible link kind for `{}`", path_str);
+ let msg = format!("incompatible link kind for `{path_str}`");
let callback = |diag: &mut Diagnostic, sp: Option<rustc_span::Span>, link_range| {
let note = format!(
"this link resolved to {} {}, which is not {} {}",
@@ -1217,6 +1235,9 @@ impl LinkCollector<'_, '_> {
// If errors are cached then they are only reported on first occurrence
// which we want in some cases but not in others.
cache_errors: bool,
+ // If this call is intended to be recoverable, then pass true to silence.
+ // This is only recoverable when path is failed to resolved.
+ recoverable: bool,
) -> Option<(Res, Option<UrlFragment>)> {
if let Some(res) = self.visited_links.get(&key) {
if res.is_some() || cache_errors {
@@ -1224,7 +1245,7 @@ impl LinkCollector<'_, '_> {
}
}
- let mut candidates = self.resolve_with_disambiguator(&key, diag.clone());
+ let mut candidates = self.resolve_with_disambiguator(&key, diag.clone(), recoverable);
// FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether.
// However I'm not sure how to check that across crates.
@@ -1275,6 +1296,9 @@ impl LinkCollector<'_, '_> {
&mut self,
key: &ResolutionInfo,
diag: DiagnosticInfo<'_>,
+ // If this call is intended to be recoverable, then pass true to silence.
+ // This is only recoverable when path is failed to resolved.
+ recoverable: bool,
) -> Vec<(Res, Option<DefId>)> {
let disambiguator = key.dis;
let path_str = &key.path_str;
@@ -1304,7 +1328,9 @@ impl LinkCollector<'_, '_> {
}
}
}
- resolution_failure(self, diag, path_str, disambiguator, smallvec![err]);
+ if !recoverable {
+ resolution_failure(self, diag, path_str, disambiguator, smallvec![err]);
+ }
return vec![];
}
}
@@ -1341,13 +1367,15 @@ impl LinkCollector<'_, '_> {
.fold(0, |acc, res| if let Ok(res) = res { acc + res.len() } else { acc });
if len == 0 {
- resolution_failure(
- self,
- diag,
- path_str,
- disambiguator,
- candidates.into_iter().filter_map(|res| res.err()).collect(),
- );
+ if !recoverable {
+ resolution_failure(
+ self,
+ diag,
+ path_str,
+ disambiguator,
+ candidates.into_iter().filter_map(|res| res.err()).collect(),
+ );
+ }
return vec![];
} else if len == 1 {
candidates.into_iter().filter_map(|res| res.ok()).flatten().collect::<Vec<_>>()
@@ -1368,6 +1396,58 @@ impl LinkCollector<'_, '_> {
}
}
}
+
+ /// Resolve display text if the provided link has separated parts of links.
+ ///
+ /// For example:
+ /// Inline link `[display_text](dest_link)` and reference link `[display_text][reference_link]` has
+ /// separated parts of links.
+ fn resolve_display_text(
+ &mut self,
+ explicit_link: &Box<str>,
+ display_res_info: ResolutionInfo,
+ ori_link: &MarkdownLink,
+ diag_info: &DiagnosticInfo<'_>,
+ ) {
+ // Check if explicit resolution's path is same as resolution of original link's display text path, see
+ // tests/rustdoc-ui/lint/redundant_explicit_links.rs for more cases.
+ //
+ // To avoid disambiguator from panicking, we check if display text path is possible to be disambiguated
+ // into explicit path.
+ if !matches!(
+ ori_link.kind,
+ LinkType::Inline | LinkType::Reference | LinkType::ReferenceUnknown
+ ) {
+ return;
+ }
+
+ // Algorithm to check if display text could possibly be the explicit link:
+ //
+ // Consider 2 links which are display text and explicit link, pick the shorter
+ // one as symbol and longer one as full qualified path, and tries to match symbol
+ // to the full qualified path's last symbol.
+ //
+ // Otherwise, check if 2 links are same, if so, skip the resolve process.
+ //
+ // Notice that this algorithm is passive, might possibly miss actual redudant cases.
+ let explicit_link = explicit_link.to_string();
+ let display_text = ori_link.display_text.as_ref().unwrap();
+
+ if display_text.len() == explicit_link.len() {
+ // Whether they are same or not, skip the resolve process.
+ return;
+ }
+
+ if explicit_link.ends_with(&display_text[..]) || display_text.ends_with(&explicit_link[..])
+ {
+ self.resolve_with_disambiguator_cached(
+ display_res_info,
+ diag_info.clone(), // this struct should really be Copy, but Range is not :(
+ false,
+ true,
+ );
+ }
+ }
}
/// Get the section of a link between the backticks,
@@ -1453,7 +1533,7 @@ impl Disambiguator {
"value" => NS(Namespace::ValueNS),
"macro" => NS(Namespace::MacroNS),
"prim" | "primitive" => Primitive,
- _ => return Err((format!("unknown disambiguator `{}`", prefix), 0..idx)),
+ _ => return Err((format!("unknown disambiguator `{prefix}`"), 0..idx)),
};
Ok(Some((d, &rest[1..], &rest[1..])))
} else {
@@ -1521,7 +1601,7 @@ enum Suggestion {
impl Suggestion {
fn descr(&self) -> Cow<'static, str> {
match self {
- Self::Prefix(x) => format!("prefix with `{}@`", x).into(),
+ Self::Prefix(x) => format!("prefix with `{x}@`").into(),
Self::Function => "add parentheses".into(),
Self::Macro => "add an exclamation mark".into(),
Self::RemoveDisambiguator => "remove the disambiguator".into(),
@@ -1531,9 +1611,9 @@ impl Suggestion {
fn as_help(&self, path_str: &str) -> String {
// FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
match self {
- Self::Prefix(prefix) => format!("{}@{}", prefix, path_str),
- Self::Function => format!("{}()", path_str),
- Self::Macro => format!("{}!", path_str),
+ Self::Prefix(prefix) => format!("{prefix}@{path_str}"),
+ Self::Function => format!("{path_str}()"),
+ Self::Macro => format!("{path_str}!"),
Self::RemoveDisambiguator => path_str.into(),
}
}
@@ -1568,7 +1648,7 @@ impl Suggestion {
match self {
Self::Prefix(prefix) => {
// FIXME: if this is an implied shortcut link, it's bad style to suggest `@`
- let mut sugg = vec![(sp.with_hi(inner_sp.lo()), format!("{}@", prefix))];
+ let mut sugg = vec![(sp.with_hi(inner_sp.lo()), format!("{prefix}@"))];
if sp.hi() != inner_sp.hi() {
sugg.push((inner_sp.shrink_to_hi().with_hi(sp.hi()), String::new()));
}
@@ -1610,10 +1690,9 @@ fn report_diagnostic(
DiagnosticInfo { item, ori_link: _, dox, link_range }: &DiagnosticInfo<'_>,
decorate: impl FnOnce(&mut Diagnostic, Option<rustc_span::Span>, MarkdownLinkRange),
) {
- let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id)
- else {
+ let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else {
// If non-local, no need to check anything.
- info!("ignoring warning from parent crate: {}", msg);
+ info!("ignoring warning from parent crate: {msg}");
return;
};
@@ -1691,15 +1770,14 @@ fn resolution_failure(
report_diagnostic(
tcx,
BROKEN_INTRA_DOC_LINKS,
- format!("unresolved link to `{}`", path_str),
+ format!("unresolved link to `{path_str}`"),
&diag_info,
|diag, sp, link_range| {
- let item = |res: Res| format!("the {} `{}`", res.descr(), res.name(tcx),);
+ let item = |res: Res| format!("the {} `{}`", res.descr(), res.name(tcx));
let assoc_item_not_allowed = |res: Res| {
let name = res.name(tcx);
format!(
- "`{}` is {} {}, not a module or type, and cannot have associated items",
- name,
+ "`{name}` is {} {}, not a module or type, and cannot have associated items",
res.article(),
res.descr()
)
@@ -1745,7 +1823,7 @@ fn resolution_failure(
name = start;
for ns in [TypeNS, ValueNS, MacroNS] {
if let Ok(v_res) = collector.resolve(start, ns, item_id, module_id) {
- debug!("found partial_res={:?}", v_res);
+ debug!("found partial_res={v_res:?}");
if !v_res.is_empty() {
*partial_res = Some(full_res(tcx, v_res[0]));
*unresolved = end.into();
@@ -1766,10 +1844,10 @@ fn resolution_failure(
let note = if partial_res.is_some() {
// Part of the link resolved; e.g. `std::io::nonexistent`
let module_name = tcx.item_name(module);
- format!("no item named `{}` in module `{}`", unresolved, module_name)
+ format!("no item named `{unresolved}` in module `{module_name}`")
} else {
// None of the link resolved; e.g. `Notimported`
- format!("no item named `{}` in scope", unresolved)
+ format!("no item named `{unresolved}` in scope")
};
if let Some(span) = sp {
diag.span_label(span, note);
@@ -1811,7 +1889,7 @@ fn resolution_failure(
Res::Primitive(_) => None,
};
let is_struct_variant = |did| {
- if let ty::Adt(def, _) = tcx.type_of(did).subst_identity().kind()
+ if let ty::Adt(def, _) = tcx.type_of(did).instantiate_identity().kind()
&& def.is_enum()
&& let Some(variant) = def.variants().iter().find(|v| v.name == res.name(tcx)) {
// ctor is `None` if variant is a struct
@@ -1860,8 +1938,13 @@ fn resolution_failure(
}
return;
}
- Trait | TyAlias | ForeignTy | OpaqueTy | ImplTraitPlaceholder
- | TraitAlias | TyParam | Static(_) => "associated item",
+ Trait
+ | TyAlias { .. }
+ | ForeignTy
+ | OpaqueTy
+ | TraitAlias
+ | TyParam
+ | Static(_) => "associated item",
Impl { .. } | GlobalAsm => unreachable!("not a path"),
}
} else {
@@ -1869,11 +1952,9 @@ fn resolution_failure(
};
let name = res.name(tcx);
let note = format!(
- "the {} `{}` has no {} named `{}`",
- res.descr(),
- name,
- disambiguator.map_or(path_description, |d| d.descr()),
- unresolved,
+ "the {res} `{name}` has no {disamb_res} named `{unresolved}`",
+ res = res.descr(),
+ disamb_res = disambiguator.map_or(path_description, |d| d.descr()),
);
if let Some(span) = sp {
diag.span_label(span, note);
@@ -1968,7 +2049,7 @@ fn report_malformed_generics(
report_diagnostic(
cx.tcx,
BROKEN_INTRA_DOC_LINKS,
- format!("unresolved link to `{}`", path_str),
+ format!("unresolved link to `{path_str}`"),
&diag_info,
|diag, sp, _link_range| {
let note = match err {
@@ -2020,7 +2101,7 @@ fn ambiguity_error(
return false;
}
- let mut msg = format!("`{}` is ", path_str);
+ let mut msg = format!("`{path_str}` is ");
match kinds.as_slice() {
[res1, res2] => {
msg += &format!(
@@ -2084,7 +2165,7 @@ fn suggest_disambiguator(
diag.span_suggestion_verbose(sp, help, suggestion_text, Applicability::MaybeIncorrect);
}
} else {
- diag.help(format!("{}: {}", help, suggestion.as_help(path_str)));
+ diag.help(format!("{help}: {}", suggestion.as_help(path_str)));
}
}
@@ -2098,8 +2179,7 @@ fn privacy_error(cx: &DocContext<'_>, diag_info: &DiagnosticInfo<'_>, path_str:
}
None => "<unknown>",
};
- let msg =
- format!("public documentation for `{}` links to private item `{}`", item_name, path_str);
+ let msg = format!("public documentation for `{item_name}` links to private item `{path_str}`");
report_diagnostic(cx.tcx, PRIVATE_INTRA_DOC_LINKS, msg, diag_info, |diag, sp, _link_range| {
if let Some(sp) = sp {
@@ -2150,6 +2230,6 @@ fn resolve_primitive(path_str: &str, ns: Namespace) -> Option<Res> {
"never" | "!" => Never,
_ => return None,
};
- debug!("resolved primitives {:?}", prim);
+ debug!("resolved primitives {prim:?}");
Some(Res::Primitive(prim))
}