Avoid collisions between traits and their derive macros
This commit is contained in:
parent
e003c3ea05
commit
27dcb4aab5
@ -12,6 +12,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
|||||||
use rustc_middle::ty;
|
use rustc_middle::ty;
|
||||||
use rustc_resolve::ParentScope;
|
use rustc_resolve::ParentScope;
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
|
use rustc_span::hygiene::MacroKind;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::symbol::Symbol;
|
use rustc_span::symbol::Symbol;
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
@ -407,6 +408,22 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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> {
|
impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
||||||
fn fold_item(&mut self, mut item: Item) -> Option<Item> {
|
fn fold_item(&mut self, mut item: Item) -> Option<Item> {
|
||||||
let item_hir_id = if item.is_mod() {
|
let item_hir_id = if item.is_mod() {
|
||||||
@ -650,7 +667,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
// Try everything!
|
// Try everything!
|
||||||
let candidates = PerNS {
|
let mut candidates = PerNS {
|
||||||
macro_ns: self
|
macro_ns: self
|
||||||
.macro_resolve(path_str, base_node)
|
.macro_resolve(path_str, base_node)
|
||||||
.map(|res| (res, extra_fragment.clone())),
|
.map(|res| (res, extra_fragment.clone())),
|
||||||
@ -705,10 +722,16 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_unambiguous = candidates.clone().present_items().count() == 1;
|
let len = candidates.clone().present_items().count();
|
||||||
if is_unambiguous {
|
|
||||||
|
if len == 1 {
|
||||||
candidates.present_items().next().unwrap()
|
candidates.present_items().next().unwrap()
|
||||||
|
} else if len == 2 && is_derive_trait_collision(&candidates) {
|
||||||
|
candidates.type_ns.unwrap()
|
||||||
} else {
|
} else {
|
||||||
|
if is_derive_trait_collision(&candidates) {
|
||||||
|
candidates.macro_ns = None;
|
||||||
|
}
|
||||||
ambiguity_error(
|
ambiguity_error(
|
||||||
cx,
|
cx,
|
||||||
&item,
|
&item,
|
||||||
|
@ -19,6 +19,11 @@ pub fn b_derive(input: TokenStream) -> TokenStream {
|
|||||||
input
|
input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro_derive(DeriveTrait)]
|
||||||
|
pub fn trait_derive(input: TokenStream) -> TokenStream {
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
#[proc_macro_attribute]
|
#[proc_macro_attribute]
|
||||||
pub fn attr_a(input: TokenStream, _args: TokenStream) -> TokenStream {
|
pub fn attr_a(input: TokenStream, _args: TokenStream) -> TokenStream {
|
||||||
input
|
input
|
||||||
|
@ -11,7 +11,11 @@ use intra_link_proc_macro_macro::{DeriveB, attr_b};
|
|||||||
|
|
||||||
// @has - '//a/@href' '../intra_link_proc_macro/derive.DeriveA.html'
|
// @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/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/derive.DeriveB.html'
|
||||||
// @has - '//a/@href' '../intra_link_proc_macro_macro/attr.attr_b.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;
|
pub struct Foo;
|
||||||
|
|
||||||
|
// this should not cause ambiguity errors
|
||||||
|
pub trait DeriveTrait {}
|
||||||
|
Loading…
Reference in New Issue
Block a user