Skip to content

Commit 2755a1b

Browse files
committed
Handle primitives in resolve_associated_item
This does _not_ fix `Self` on primitives because it doesn't have a way to go from the `DefId` of a lang_item to the corresponding `PrimTy`. However once that's fixed, this commit will be necessary.
1 parent 7c74b37 commit 2755a1b

File tree

1 file changed

+45
-43
lines changed

1 file changed

+45
-43
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 45 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -304,48 +304,6 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
304304
})?;
305305
debug!("split {} into {} and {}", path_str, path_root, item_name);
306306

307-
// TODO(#77267): this should really be part of `resolve_associated_item`
308-
if let Some((path, prim)) = is_primitive(&path_root, TypeNS) {
309-
let impls =
310-
primitive_impl(cx, &path).ok_or_else(|| ResolutionFailure::NotResolved {
311-
module_id,
312-
partial_res: Some(prim),
313-
unresolved: item_str.into(),
314-
})?;
315-
for &impl_ in impls {
316-
let link = cx
317-
.tcx
318-
.associated_items(impl_)
319-
.find_by_name_and_namespace(
320-
cx.tcx,
321-
Ident::with_dummy_span(item_name),
322-
ns,
323-
impl_,
324-
)
325-
.map(|item| match item.kind {
326-
ty::AssocKind::Fn => "method",
327-
ty::AssocKind::Const => "associatedconstant",
328-
ty::AssocKind::Type => "associatedtype",
329-
})
330-
.map(|out| (prim, Some(format!("{}#{}.{}", path, out, item_str))));
331-
if let Some(link) = link {
332-
return Ok(link);
333-
}
334-
}
335-
debug!(
336-
"returning primitive error for {}::{} in {} namespace",
337-
path,
338-
item_name,
339-
ns.descr()
340-
);
341-
return Err(ResolutionFailure::NotResolved {
342-
module_id,
343-
partial_res: Some(prim),
344-
unresolved: item_str.into(),
345-
}
346-
.into());
347-
}
348-
349307
let ty_res = cx
350308
.enter_resolver(|resolver| {
351309
// only types can have associated items
@@ -534,6 +492,48 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
534492
Ok((res, Some(format!("{}.{}", kind, item_str))))
535493
}
536494
}),
495+
Res::PrimTy(prim) => {
496+
let path = prim.name_str();
497+
let impls =
498+
primitive_impl(cx, &path).ok_or_else(|| ResolutionFailure::NotResolved {
499+
module_id,
500+
partial_res: Some(ty_res),
501+
unresolved: item_str.into(),
502+
})?;
503+
for &impl_ in impls {
504+
let link = cx
505+
.tcx
506+
.associated_items(impl_)
507+
.find_by_name_and_namespace(
508+
cx.tcx,
509+
Ident::with_dummy_span(item_name),
510+
ns,
511+
impl_,
512+
)
513+
.map(|item| match item.kind {
514+
ty::AssocKind::Fn => "method",
515+
ty::AssocKind::Const => "associatedconstant",
516+
ty::AssocKind::Type => "associatedtype",
517+
})
518+
.map(|out| (ty_res, Some(format!("{}#{}.{}", path, out, item_str))));
519+
if let Some(link) = link {
520+
return Ok(link);
521+
}
522+
}
523+
debug!(
524+
"returning primitive error for {}::{} in {} namespace",
525+
path,
526+
item_name,
527+
ns.descr()
528+
);
529+
// primitives will never have a variant field
530+
Some(Err(ResolutionFailure::NotResolved {
531+
module_id,
532+
partial_res: Some(ty_res),
533+
unresolved: item_str.into(),
534+
}
535+
.into()))
536+
}
537537
_ => None,
538538
};
539539
res.unwrap_or_else(|| {
@@ -796,19 +796,21 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
796796
// As a workaround, see if the parent of the item is an `impl`; if so this must be an associated item,
797797
// regardless of what rustdoc wants to call it.
798798
} else if let Some(parent) = self.cx.tcx.parent(item.def_id) {
799+
debug!("saw parent {:?} for item {:?}", parent, item.def_id);
799800
let parent_kind = self.cx.tcx.def_kind(parent);
800801
Some(if parent_kind == DefKind::Impl { parent } else { item.def_id })
801802
} else {
802803
// FIXME: this should really be `Some(item.def_id)`, but for some reason that panics in `opt_item_name`
803804
None
804805
};
805-
// TODO: account for primitives too?
806+
// FIXME(75809): account for primitives too
806807
let self_id = self_id.and_then(|id| {
807808
let kind = self.cx.tcx.def_kind(id);
808809
let id = if kind == DefKind::Impl {
809810
if let ty::TyKind::Adt(def, _) = self.cx.tcx.type_of(id).kind() {
810811
def.did
811812
} else {
813+
debug!("saw impl for non-adt {:?}", id);
812814
return None;
813815
}
814816
} else {

0 commit comments

Comments
 (0)