diff options
| author | Joshua Nelson <jyn514@gmail.com> | 2020-08-06 18:11:47 -0400 |
|---|---|---|
| committer | Joshua Nelson <jyn514@gmail.com> | 2020-08-06 18:16:10 -0400 |
| commit | 0c99d806eabd32a2ee2e6c71b400222b99c659e1 (patch) | |
| tree | f168d4df6e7904113b48d776d8b63a1525a57f9f | |
| parent | f05e9da493a9e447dd2dafc271b06ad80358496f (diff) | |
| download | rust-0c99d806eabd32a2ee2e6c71b400222b99c659e1.tar.gz rust-0c99d806eabd32a2ee2e6c71b400222b99c659e1.zip | |
Use the proper kind for associated items
See comments in the diff; this is such a hack. The reason this can't be done properly in `register_res` is because there's no way to get back the parent type: calling `tcx.parent(assoc_item)` gets you the _impl_, not the type. You can call `tcx.impl_trait_ref(impl_).self_ty()`, but there's no way to go from that to a DefId without unwrapping.
3 files changed, 25 insertions, 13 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index a119e67ed7b..7f3bb13edd7 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -17,6 +17,7 @@ use rustc_span::symbol::Ident; use rustc_span::symbol::Symbol; use rustc_span::DUMMY_SP; +use std::cell::Cell; use std::ops::Range; use crate::clean::*; @@ -62,11 +63,12 @@ struct LinkCollector<'a, 'tcx> { cx: &'a DocContext<'tcx>, // NOTE: this may not necessarily be a module in the current crate mod_ids: Vec<DefId>, + kind_side_channel: Cell<Option<DefKind>>, } impl<'a, 'tcx> LinkCollector<'a, 'tcx> { fn new(cx: &'a DocContext<'tcx>) -> Self { - LinkCollector { cx, mod_ids: Vec::new() } + LinkCollector { cx, mod_ids: Vec::new(), kind_side_channel: Cell::new(None) } } fn variant_field( @@ -347,6 +349,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { AnchorFailure::AssocConstant })) } else { + // HACK(jynelson): `clean` expects the type, not the associated item. + // but the disambiguator logic expects the associated item. + // Store the kind in a side channel so that only the disambiguator logic looks at it. + self.kind_side_channel.replace(Some(item.kind.as_def_kind())); Ok((ty_res, Some(format!("{}.{}", out, item_name)))) } } else { @@ -763,7 +769,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> { debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); // NOTE: this relies on the fact that `''` is never parsed as a disambiguator // NOTE: this needs to be kept in sync with the disambiguator parsing - match (kind, disambiguator) { + match (self.kind_side_channel.take().unwrap_or(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 // This can't cause ambiguity because both are in the same namespace. diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs index 1a7a2fce7a3..5af2ff06994 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs @@ -2,6 +2,10 @@ //~^ NOTE lint level is defined pub enum S {} +impl S { + fn assoc_fn() {} +} + macro_rules! m { () => {}; } @@ -65,4 +69,6 @@ trait T {} //~^ ERROR incompatible link kind for `f` //~| NOTE this link resolved //~| HELP use its disambiguator + +/// Link to [S::assoc_fn()] pub fn f() {} diff --git a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr index 9edf838f9d8..7cf15db6017 100644 --- a/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr +++ b/src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr @@ -1,5 +1,5 @@ error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:14:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:18:14 | LL | /// Link to [struct@S] | ^^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -12,7 +12,7 @@ LL | #![deny(broken_intra_doc_links)] = note: this link resolved to an enum, which is not a struct error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:19:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:23:14 | LL | /// Link to [mod@S] | ^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -20,7 +20,7 @@ LL | /// Link to [mod@S] = note: this link resolved to an enum, which is not a module error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:24:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:28:14 | LL | /// Link to [union@S] | ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -28,7 +28,7 @@ LL | /// Link to [union@S] = note: this link resolved to an enum, which is not a union error: incompatible link kind for `S` - --> $DIR/intra-links-disambiguator-mismatch.rs:29:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:33:14 | LL | /// Link to [trait@S] | ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S` @@ -36,7 +36,7 @@ LL | /// Link to [trait@S] = note: this link resolved to an enum, which is not a trait error: incompatible link kind for `T` - --> $DIR/intra-links-disambiguator-mismatch.rs:34:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:38:14 | LL | /// Link to [struct@T] | ^^^^^^^^ help: to link to the trait, use its disambiguator: `trait@T` @@ -44,7 +44,7 @@ LL | /// Link to [struct@T] = note: this link resolved to a trait, which is not a struct error: incompatible link kind for `m` - --> $DIR/intra-links-disambiguator-mismatch.rs:39:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:43:14 | LL | /// Link to [derive@m] | ^^^^^^^^ help: to link to the macro, use its disambiguator: `m!` @@ -52,7 +52,7 @@ LL | /// Link to [derive@m] = note: this link resolved to a macro, which is not a derive macro error: incompatible link kind for `s` - --> $DIR/intra-links-disambiguator-mismatch.rs:44:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:48:14 | LL | /// Link to [const@s] | ^^^^^^^ help: to link to the static, use its disambiguator: `static@s` @@ -60,7 +60,7 @@ LL | /// Link to [const@s] = note: this link resolved to a static, which is not a constant error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:49:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:53:14 | LL | /// Link to [static@c] | ^^^^^^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -68,7 +68,7 @@ LL | /// Link to [static@c] = note: this link resolved to a constant, which is not a static error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:54:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:58:14 | LL | /// Link to [fn@c] | ^^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -76,7 +76,7 @@ LL | /// Link to [fn@c] = note: this link resolved to a constant, which is not a function error: incompatible link kind for `c` - --> $DIR/intra-links-disambiguator-mismatch.rs:59:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:63:14 | LL | /// Link to [c()] | ^^^ help: to link to the constant, use its disambiguator: `const@c` @@ -84,7 +84,7 @@ LL | /// Link to [c()] = note: this link resolved to a constant, which is not a function error: incompatible link kind for `f` - --> $DIR/intra-links-disambiguator-mismatch.rs:64:14 + --> $DIR/intra-links-disambiguator-mismatch.rs:68:14 | LL | /// Link to [const@f] | ^^^^^^^ help: to link to the function, use its disambiguator: `f()` |
