use rustc_middle::ty;
use rustc_resolve::ParentScope;
use rustc_session::lint;
+use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::Ident;
use rustc_span::symbol::Symbol;
use rustc_span::DUMMY_SP;
}
}
+/// Check for resolve collisions between a trait and its derive
+///
+/// These are common and we should just resolve to the trait in that case
+fn is_derive_trait_collision<T>(ns: &PerNS<Option<(Res, T)>>) -> bool {
+ if let PerNS {
+ type_ns: Some((Res::Def(DefKind::Trait, _), _)),
+ macro_ns: Some((Res::Def(DefKind::Macro(MacroKind::Derive), _), _)),
+ ..
+ } = *ns
+ {
+ true
+ } else {
+ false
+ }
+}
+
impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
fn fold_item(&mut self, mut item: Item) -> Option<Item> {
let item_hir_id = if item.is_mod() {
}
None => {
// Try everything!
- let candidates = PerNS {
+ let mut candidates = PerNS {
macro_ns: self
.macro_resolve(path_str, base_node)
.map(|res| (res, extra_fragment.clone())),
continue;
}
- let is_unambiguous = candidates.clone().present_items().count() == 1;
- if is_unambiguous {
+ let len = candidates.clone().present_items().count();
+
+ if len == 1 {
candidates.present_items().next().unwrap()
+ } else if len == 2 && is_derive_trait_collision(&candidates) {
+ candidates.type_ns.unwrap()
} else {
+ if is_derive_trait_collision(&candidates) {
+ candidates.macro_ns = None;
+ }
ambiguity_error(
cx,
&item,
// @has - '//a/@href' '../intra_link_proc_macro/derive.DeriveA.html'
// @has - '//a/@href' '../intra_link_proc_macro/attr.attr_a.html'
+// @has - '//a/@href' '../intra_link_proc_macro/trait.DeriveTrait.html'
// @has - '//a/@href' '../intra_link_proc_macro_macro/derive.DeriveB.html'
// @has - '//a/@href' '../intra_link_proc_macro_macro/attr.attr_b.html'
-/// Link to [DeriveA], [attr_a], [DeriveB], [attr_b]
+/// Link to [DeriveA], [attr_a], [DeriveB], [attr_b], [DeriveTrait]
pub struct Foo;
+
+// this should not cause ambiguity errors
+pub trait DeriveTrait {}