Skip to content

Commit c39521a

Browse files
committed
Detect and resolve amibiguities in fn parameters type names
Fixes: rust-lang#122673
1 parent 03994e4 commit c39521a

File tree

2 files changed

+71
-1
lines changed

2 files changed

+71
-1
lines changed

src/librustdoc/html/format.rs

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ use std::borrow::Cow;
1111
use std::cell::Cell;
1212
use std::fmt::{self, Display, Write};
1313
use std::iter::{self, once};
14+
use std::rc::Rc;
1415

1516
use rustc_ast as ast;
1617
use rustc_attr::{ConstStability, StabilityLevel};
1718
use rustc_data_structures::captures::Captures;
19+
use rustc_data_structures::fx::FxHashMap;
1820
use rustc_data_structures::fx::FxHashSet;
1921
use rustc_hir as hir;
2022
use rustc_hir::def::DefKind;
@@ -1418,6 +1420,53 @@ impl clean::FnDecl {
14181420
})
14191421
}
14201422

1423+
fn ambiguities<'a>(
1424+
types: impl Iterator<Item = &'a clean::Type>,
1425+
) -> FxHashMap<DefId, Rc<Cell<bool>>> {
1426+
fn inner(
1427+
ty: &clean::Type,
1428+
res_map: &mut FxHashMap<DefId, Rc<Cell<bool>>>,
1429+
conflict_map: &mut FxHashMap<Symbol, Rc<Cell<bool>>>,
1430+
) {
1431+
match ty {
1432+
clean::Type::Path { path } => {
1433+
res_map.entry(path.def_id()).or_insert_with(|| {
1434+
let last = path.last();
1435+
conflict_map
1436+
.entry(last)
1437+
.and_modify(|b| {
1438+
b.replace(true);
1439+
})
1440+
.or_insert_with(|| Rc::new(Cell::new(false)))
1441+
.clone()
1442+
});
1443+
}
1444+
clean::Type::Tuple(types) => {
1445+
for ty in types {
1446+
inner(ty, res_map, conflict_map)
1447+
}
1448+
}
1449+
clean::Type::Slice(ty)
1450+
| clean::Type::Array(ty, _)
1451+
| clean::Type::RawPointer(_, ty)
1452+
| clean::Type::BorrowedRef { type_: ty, .. } => inner(ty, res_map, conflict_map),
1453+
clean::Type::QPath(_)
1454+
| clean::Type::Infer
1455+
| clean::Type::ImplTrait(_)
1456+
| clean::Type::BareFunction(_)
1457+
| clean::Type::Primitive(_)
1458+
| clean::Type::Generic(_)
1459+
| clean::Type::DynTrait(_, _) => (),
1460+
}
1461+
}
1462+
let mut res_map = FxHashMap::default();
1463+
let mut conflict_map = FxHashMap::default();
1464+
for ty in types {
1465+
inner(ty, &mut res_map, &mut conflict_map)
1466+
}
1467+
res_map
1468+
}
1469+
14211470
fn inner_full_print(
14221471
&self,
14231472
// For None, the declaration will not be line-wrapped. For Some(n),
@@ -1434,6 +1483,7 @@ impl clean::FnDecl {
14341483
{
14351484
write!(f, "\n{}", Indent(n + 4))?;
14361485
}
1486+
let ambiguities = Self::ambiguities(self.inputs.values.iter().map(|inpt| &inpt.type_));
14371487
for (i, input) in self.inputs.values.iter().enumerate() {
14381488
if i > 0 {
14391489
match line_wrapping_indent {
@@ -1471,7 +1521,14 @@ impl clean::FnDecl {
14711521
write!(f, "const ")?;
14721522
}
14731523
write!(f, "{}: ", input.name)?;
1474-
input.type_.print(cx).fmt(f)?;
1524+
1525+
let use_absolute = input
1526+
.type_
1527+
.def_id(cx.cache())
1528+
.and_then(|did| ambiguities.get(&did))
1529+
.map(|rcb| rcb.get())
1530+
.unwrap_or(false);
1531+
fmt_type(&input.type_, f, use_absolute, cx)?;
14751532
}
14761533
}
14771534

tests/rustdoc/fn_param_ambiguities.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
pub mod X {
2+
pub enum A {}
3+
pub enum B {}
4+
pub enum C {}
5+
}
6+
7+
pub mod Y {
8+
pub enum A {}
9+
pub enum B {}
10+
}
11+
12+
// @has fn_param_ambiguities/fn.f.html //pre 'pub fn f(xa: fn_param_ambiguities::X::A, ya: fn_param_ambiguities::Y::A, yb: B, xc: C)'
13+
pub fn f(xa: X::A, ya: Y::A, yb : Y::B, xc: X::C) {}

0 commit comments

Comments
 (0)