Skip to content

Commit 0c99d80

Browse files
committed
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.
1 parent f05e9da commit 0c99d80

File tree

3 files changed

+25
-13
lines changed

3 files changed

+25
-13
lines changed

src/librustdoc/passes/collect_intra_doc_links.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use rustc_span::symbol::Ident;
1717
use rustc_span::symbol::Symbol;
1818
use rustc_span::DUMMY_SP;
1919

20+
use std::cell::Cell;
2021
use std::ops::Range;
2122

2223
use crate::clean::*;
@@ -62,11 +63,12 @@ struct LinkCollector<'a, 'tcx> {
6263
cx: &'a DocContext<'tcx>,
6364
// NOTE: this may not necessarily be a module in the current crate
6465
mod_ids: Vec<DefId>,
66+
kind_side_channel: Cell<Option<DefKind>>,
6567
}
6668

6769
impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
6870
fn new(cx: &'a DocContext<'tcx>) -> Self {
69-
LinkCollector { cx, mod_ids: Vec::new() }
71+
LinkCollector { cx, mod_ids: Vec::new(), kind_side_channel: Cell::new(None) }
7072
}
7173

7274
fn variant_field(
@@ -347,6 +349,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
347349
AnchorFailure::AssocConstant
348350
}))
349351
} else {
352+
// HACK(jynelson): `clean` expects the type, not the associated item.
353+
// but the disambiguator logic expects the associated item.
354+
// Store the kind in a side channel so that only the disambiguator logic looks at it.
355+
self.kind_side_channel.replace(Some(item.kind.as_def_kind()));
350356
Ok((ty_res, Some(format!("{}.{}", out, item_name))))
351357
}
352358
} else {
@@ -763,7 +769,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
763769
debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator);
764770
// NOTE: this relies on the fact that `''` is never parsed as a disambiguator
765771
// NOTE: this needs to be kept in sync with the disambiguator parsing
766-
match (kind, disambiguator) {
772+
match (self.kind_side_channel.take().unwrap_or(kind), disambiguator) {
767773
| (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const)))
768774
// NOTE: this allows 'method' to mean both normal functions and associated functions
769775
// This can't cause ambiguity because both are in the same namespace.

src/test/rustdoc-ui/intra-links-disambiguator-mismatch.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
//~^ NOTE lint level is defined
33
pub enum S {}
44

5+
impl S {
6+
fn assoc_fn() {}
7+
}
8+
59
macro_rules! m {
610
() => {};
711
}
@@ -65,4 +69,6 @@ trait T {}
6569
//~^ ERROR incompatible link kind for `f`
6670
//~| NOTE this link resolved
6771
//~| HELP use its disambiguator
72+
73+
/// Link to [S::assoc_fn()]
6874
pub fn f() {}

src/test/rustdoc-ui/intra-links-disambiguator-mismatch.stderr

+11-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: incompatible link kind for `S`
2-
--> $DIR/intra-links-disambiguator-mismatch.rs:14:14
2+
--> $DIR/intra-links-disambiguator-mismatch.rs:18:14
33
|
44
LL | /// Link to [struct@S]
55
| ^^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S`
@@ -12,79 +12,79 @@ LL | #![deny(broken_intra_doc_links)]
1212
= note: this link resolved to an enum, which is not a struct
1313

1414
error: incompatible link kind for `S`
15-
--> $DIR/intra-links-disambiguator-mismatch.rs:19:14
15+
--> $DIR/intra-links-disambiguator-mismatch.rs:23:14
1616
|
1717
LL | /// Link to [mod@S]
1818
| ^^^^^ help: to link to the enum, use its disambiguator: `enum@S`
1919
|
2020
= note: this link resolved to an enum, which is not a module
2121

2222
error: incompatible link kind for `S`
23-
--> $DIR/intra-links-disambiguator-mismatch.rs:24:14
23+
--> $DIR/intra-links-disambiguator-mismatch.rs:28:14
2424
|
2525
LL | /// Link to [union@S]
2626
| ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S`
2727
|
2828
= note: this link resolved to an enum, which is not a union
2929

3030
error: incompatible link kind for `S`
31-
--> $DIR/intra-links-disambiguator-mismatch.rs:29:14
31+
--> $DIR/intra-links-disambiguator-mismatch.rs:33:14
3232
|
3333
LL | /// Link to [trait@S]
3434
| ^^^^^^^ help: to link to the enum, use its disambiguator: `enum@S`
3535
|
3636
= note: this link resolved to an enum, which is not a trait
3737

3838
error: incompatible link kind for `T`
39-
--> $DIR/intra-links-disambiguator-mismatch.rs:34:14
39+
--> $DIR/intra-links-disambiguator-mismatch.rs:38:14
4040
|
4141
LL | /// Link to [struct@T]
4242
| ^^^^^^^^ help: to link to the trait, use its disambiguator: `trait@T`
4343
|
4444
= note: this link resolved to a trait, which is not a struct
4545

4646
error: incompatible link kind for `m`
47-
--> $DIR/intra-links-disambiguator-mismatch.rs:39:14
47+
--> $DIR/intra-links-disambiguator-mismatch.rs:43:14
4848
|
4949
LL | /// Link to [derive@m]
5050
| ^^^^^^^^ help: to link to the macro, use its disambiguator: `m!`
5151
|
5252
= note: this link resolved to a macro, which is not a derive macro
5353

5454
error: incompatible link kind for `s`
55-
--> $DIR/intra-links-disambiguator-mismatch.rs:44:14
55+
--> $DIR/intra-links-disambiguator-mismatch.rs:48:14
5656
|
5757
LL | /// Link to [const@s]
5858
| ^^^^^^^ help: to link to the static, use its disambiguator: `static@s`
5959
|
6060
= note: this link resolved to a static, which is not a constant
6161

6262
error: incompatible link kind for `c`
63-
--> $DIR/intra-links-disambiguator-mismatch.rs:49:14
63+
--> $DIR/intra-links-disambiguator-mismatch.rs:53:14
6464
|
6565
LL | /// Link to [static@c]
6666
| ^^^^^^^^ help: to link to the constant, use its disambiguator: `const@c`
6767
|
6868
= note: this link resolved to a constant, which is not a static
6969

7070
error: incompatible link kind for `c`
71-
--> $DIR/intra-links-disambiguator-mismatch.rs:54:14
71+
--> $DIR/intra-links-disambiguator-mismatch.rs:58:14
7272
|
7373
LL | /// Link to [fn@c]
7474
| ^^^^ help: to link to the constant, use its disambiguator: `const@c`
7575
|
7676
= note: this link resolved to a constant, which is not a function
7777

7878
error: incompatible link kind for `c`
79-
--> $DIR/intra-links-disambiguator-mismatch.rs:59:14
79+
--> $DIR/intra-links-disambiguator-mismatch.rs:63:14
8080
|
8181
LL | /// Link to [c()]
8282
| ^^^ help: to link to the constant, use its disambiguator: `const@c`
8383
|
8484
= note: this link resolved to a constant, which is not a function
8585

8686
error: incompatible link kind for `f`
87-
--> $DIR/intra-links-disambiguator-mismatch.rs:64:14
87+
--> $DIR/intra-links-disambiguator-mismatch.rs:68:14
8888
|
8989
LL | /// Link to [const@f]
9090
| ^^^^^^^ help: to link to the function, use its disambiguator: `f()`

0 commit comments

Comments
 (0)