Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 27dcb4a

Browse files
committed
Avoid collisions between traits and their derive macros
1 parent e003c3e commit 27dcb4a

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
1212
use rustc_middle::ty;
1313
use rustc_resolve::ParentScope;
1414
use rustc_session::lint;
15+
use rustc_span::hygiene::MacroKind;
1516
use rustc_span::symbol::Ident;
1617
use rustc_span::symbol::Symbol;
1718
use rustc_span::DUMMY_SP;
@@ -407,6 +408,22 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
407408
}
408409
}
409410

411+
/// Check for resolve collisions between a trait and its derive
412+
///
413+
/// These are common and we should just resolve to the trait in that case
414+
fn is_derive_trait_collision<T>(ns: &PerNS<Option<(Res, T)>>) -> bool {
415+
if let PerNS {
416+
type_ns: Some((Res::Def(DefKind::Trait, _), _)),
417+
macro_ns: Some((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)),
418+
..
419+
} = *ns
420+
{
421+
true
422+
} else {
423+
false
424+
}
425+
}
426+
410427
impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
411428
fn fold_item(&mut self, mut item: Item) -> Option<Item> {
412429
let item_hir_id = if item.is_mod() {
@@ -650,7 +667,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
650667
}
651668
None => {
652669
// Try everything!
653-
let candidates = PerNS {
670+
let mut candidates = PerNS {
654671
macro_ns: self
655672
.macro_resolve(path_str, base_node)
656673
.map(|res| (res, extra_fragment.clone())),
@@ -705,10 +722,16 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
705722
continue;
706723
}
707724

708-
let is_unambiguous = candidates.clone().present_items().count() == 1;
709-
if is_unambiguous {
725+
let len = candidates.clone().present_items().count();
726+
727+
if len == 1 {
710728
candidates.present_items().next().unwrap()
729+
} else if len == 2 && is_derive_trait_collision(&candidates) {
730+
candidates.type_ns.unwrap()
711731
} else {
732+
if is_derive_trait_collision(&candidates) {
733+
candidates.macro_ns = None;
734+
}
712735
ambiguity_error(
713736
cx,
714737
&item,

src/test/rustdoc/auxiliary/intra-link-proc-macro-macro.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ pub fn b_derive(input: TokenStream) -> TokenStream {
1919
input
2020
}
2121

22+
#[proc_macro_derive(DeriveTrait)]
23+
pub fn trait_derive(input: TokenStream) -> TokenStream {
24+
input
25+
}
26+
2227
#[proc_macro_attribute]
2328
pub fn attr_a(input: TokenStream, _args: TokenStream) -> TokenStream {
2429
input

src/test/rustdoc/intra-link-proc-macro.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ use intra_link_proc_macro_macro::{DeriveB, attr_b};
1111

1212
// @has - '//a/@href' '../intra_link_proc_macro/derive.DeriveA.html'
1313
// @has - '//a/@href' '../intra_link_proc_macro/attr.attr_a.html'
14+
// @has - '//a/@href' '../intra_link_proc_macro/trait.DeriveTrait.html'
1415
// @has - '//a/@href' '../intra_link_proc_macro_macro/derive.DeriveB.html'
1516
// @has - '//a/@href' '../intra_link_proc_macro_macro/attr.attr_b.html'
16-
/// Link to [DeriveA], [attr_a], [DeriveB], [attr_b]
17+
/// Link to [DeriveA], [attr_a], [DeriveB], [attr_b], [DeriveTrait]
1718
pub struct Foo;
19+
20+
// this should not cause ambiguity errors
21+
pub trait DeriveTrait {}

0 commit comments

Comments
 (0)