,
f: &mut fmt::Formatter<'_>,
cx: &Context<'_>,
+ at: &AmbiguityTable<'_>,
) -> fmt::Result {
let amp = if f.alternate() { "&" } else { "&" };
@@ -1463,7 +1549,7 @@ impl clean::FnDecl {
}
clean::SelfExplicit(ref typ) => {
write!(f, "self: ")?;
- typ.print(cx).fmt(f)?;
+ typ.print(&cx, at).fmt(f)?;
}
}
} else {
@@ -1471,7 +1557,8 @@ impl clean::FnDecl {
write!(f, "const ")?;
}
write!(f, "{}: ", input.name)?;
- input.type_.print(cx).fmt(f)?;
+
+ fmt_type(&input.type_, f, false, &cx, at)?;
}
}
@@ -1487,19 +1574,20 @@ impl clean::FnDecl {
Some(n) => write!(f, "\n{})", Indent(n))?,
};
- self.print_output(cx).fmt(f)
+ self.print_output(&cx, at).fmt(f)
}
fn print_output<'a, 'tcx: 'a>(
&'a self,
cx: &'a Context<'tcx>,
+ at: &'a AmbiguityTable<'_>,
) -> impl Display + 'a + Captures<'tcx> {
display_fn(move |f| match &self.output {
clean::Tuple(tys) if tys.is_empty() => Ok(()),
ty if f.alternate() => {
- write!(f, " -> {:#}", ty.print(cx))
+ write!(f, " -> {:#}", ty.print(cx, at))
}
- ty => write!(f, " -> {}", ty.print(cx)),
+ ty => write!(f, " -> {}", ty.print(cx, at)),
})
}
}
@@ -1647,20 +1735,21 @@ impl clean::Import {
pub(crate) fn print<'a, 'tcx: 'a>(
&'a self,
cx: &'a Context<'tcx>,
+ at: &'a AmbiguityTable<'_>,
) -> impl Display + 'a + Captures<'tcx> {
display_fn(move |f| match self.kind {
clean::ImportKind::Simple(name) => {
if name == self.source.path.last() {
- write!(f, "use {};", self.source.print(cx))
+ write!(f, "use {};", self.source.print(cx, at))
} else {
- write!(f, "use {source} as {name};", source = self.source.print(cx))
+ write!(f, "use {source} as {name};", source = self.source.print(cx, at))
}
}
clean::ImportKind::Glob => {
if self.source.path.segments.is_empty() {
write!(f, "use *;")
} else {
- write!(f, "use {}::*;", self.source.print(cx))
+ write!(f, "use {}::*;", self.source.print(cx, at))
}
}
})
@@ -1671,9 +1760,10 @@ impl clean::ImportSource {
pub(crate) fn print<'a, 'tcx: 'a>(
&'a self,
cx: &'a Context<'tcx>,
+ at: &'a AmbiguityTable<'_>,
) -> impl Display + 'a + Captures<'tcx> {
display_fn(move |f| match self.did {
- Some(did) => resolved_path(f, did, &self.path, true, false, cx),
+ Some(did) => resolved_path(f, did, &self.path, true, false, cx, at),
_ => {
for seg in &self.path.segments[..self.path.segments.len() - 1] {
write!(f, "{}::", seg.name)?;
@@ -1699,19 +1789,20 @@ impl clean::TypeBinding {
pub(crate) fn print<'a, 'tcx: 'a>(
&'a self,
cx: &'a Context<'tcx>,
+ at: &'a AmbiguityTable<'_>,
) -> impl Display + 'a + Captures<'tcx> {
display_fn(move |f| {
f.write_str(self.assoc.name.as_str())?;
- self.assoc.args.print(cx).fmt(f)?;
+ self.assoc.args.print(cx, at).fmt(f)?;
match self.kind {
clean::TypeBindingKind::Equality { ref term } => {
f.write_str(" = ")?;
- term.print(cx).fmt(f)?;
+ term.print(cx, at).fmt(f)?;
}
clean::TypeBindingKind::Constraint { ref bounds } => {
if !bounds.is_empty() {
f.write_str(": ")?;
- print_generic_bounds(bounds, cx).fmt(f)?;
+ print_generic_bounds(bounds, cx, at).fmt(f)?;
}
}
}
@@ -1738,10 +1829,11 @@ impl clean::GenericArg {
pub(crate) fn print<'a, 'tcx: 'a>(
&'a self,
cx: &'a Context<'tcx>,
+ at: &'a AmbiguityTable<'_>,
) -> impl Display + 'a + Captures<'tcx> {
display_fn(move |f| match self {
clean::GenericArg::Lifetime(lt) => lt.print().fmt(f),
- clean::GenericArg::Type(ty) => ty.print(cx).fmt(f),
+ clean::GenericArg::Type(ty) => ty.print(cx, at).fmt(f),
clean::GenericArg::Const(ct) => ct.print(cx.tcx()).fmt(f),
clean::GenericArg::Infer => Display::fmt("_", f),
})
@@ -1752,9 +1844,10 @@ impl clean::Term {
pub(crate) fn print<'a, 'tcx: 'a>(
&'a self,
cx: &'a Context<'tcx>,
+ at: &'a AmbiguityTable<'_>,
) -> impl Display + 'a + Captures<'tcx> {
display_fn(move |f| match self {
- clean::Term::Type(ty) => ty.print(cx).fmt(f),
+ clean::Term::Type(ty) => ty.print(cx, at).fmt(f),
clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f),
})
}
diff --git a/src/librustdoc/html/mod.rs b/src/librustdoc/html/mod.rs
index 481ed16c05f7e..2a7835c13cfe5 100644
--- a/src/librustdoc/html/mod.rs
+++ b/src/librustdoc/html/mod.rs
@@ -1,3 +1,4 @@
+mod ambiguity;
pub(crate) mod escape;
pub(crate) mod format;
pub(crate) mod highlight;
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index f1887684797a6..6634fa8376f35 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -82,6 +82,8 @@ use crate::scrape_examples::{CallData, CallLocation};
use crate::try_none;
use crate::DOC_RUST_LANG_ORG_CHANNEL;
+use super::ambiguity::AmbiguityTable;
+
pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
crate::html::format::display_fn(move |f| {
if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) }
@@ -878,6 +880,7 @@ fn assoc_const(
indent: usize,
cx: &Context<'_>,
) {
+ let at = AmbiguityTable::empty();
let tcx = cx.tcx();
write!(
w,
@@ -886,8 +889,8 @@ fn assoc_const(
vis = visibility_print_with_space(it, cx),
href = assoc_href_attr(it, link, cx),
name = it.name.as_ref().unwrap(),
- generics = generics.print(cx),
- ty = ty.print(cx),
+ generics = generics.print(cx, &at),
+ ty = ty.print(cx, &at),
);
if let Some(default) = default {
w.write_str(" = ");
@@ -899,7 +902,7 @@ fn assoc_const(
// Find a way to print constants here without all that jazz.
write!(w, "{}", Escape(&default.value(tcx).unwrap_or_else(|| default.expr(tcx))));
}
- write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline));
+ write!(w, "{}", print_where_clause(generics, cx, &at, indent, Ending::NoNewline));
}
fn assoc_type(
@@ -912,6 +915,7 @@ fn assoc_type(
indent: usize,
cx: &Context<'_>,
) {
+ let at = AmbiguityTable::empty();
write!(
w,
"{indent}{vis}type {name}{generics}",
@@ -919,16 +923,16 @@ fn assoc_type(
vis = visibility_print_with_space(it, cx),
href = assoc_href_attr(it, link, cx),
name = it.name.as_ref().unwrap(),
- generics = generics.print(cx),
+ generics = generics.print(cx, &at),
);
if !bounds.is_empty() {
- write!(w, ": {}", print_generic_bounds(bounds, cx))
+ write!(w, ": {}", print_generic_bounds(bounds, cx, &at))
}
// Render the default before the where-clause which aligns with the new recommended style. See #89122.
if let Some(default) = default {
- write!(w, " = {}", default.print(cx))
+ write!(w, " = {}", default.print(cx, &at))
}
- write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline));
+ write!(w, "{}", print_where_clause(generics, cx, &at, indent, Ending::NoNewline));
}
fn assoc_method(
@@ -946,6 +950,7 @@ fn assoc_method(
let name = meth.name.as_ref().unwrap();
let vis = visibility_print_with_space(meth, cx).to_string();
let defaultness = print_default_space(meth.is_default());
+ let at = AmbiguityTable::build_fn_decl(d);
// FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove
// this condition.
let constness = match render_mode {
@@ -960,7 +965,7 @@ fn assoc_method(
let href = assoc_href_attr(meth, link, cx);
// NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
- let generics_len = format!("{:#}", g.print(cx)).len();
+ let generics_len = format!("{:#}", g.print(cx, &at)).len();
let mut header_len = "fn ".len()
+ vis.len()
+ defaultness.len()
@@ -996,10 +1001,10 @@ fn assoc_method(
abi = abi,
href = href,
name = name,
- generics = g.print(cx),
- decl = d.full_print(header_len, indent, cx),
+ generics = g.print(cx, &at),
+ decl = d.full_print(header_len, indent, cx, &at),
notable_traits = notable_traits.unwrap_or_default(),
- where_clause = print_where_clause(g, cx, indent, end_newline),
+ where_clause = print_where_clause(g, cx, &at, indent, end_newline),
);
}
@@ -1288,6 +1293,7 @@ fn render_assoc_items_inner(
what: AssocItemRender<'_>,
derefs: &mut DefIdSet,
) {
+ let at = AmbiguityTable::empty();
info!("Documenting associated items of {:?}", containing_item.name);
let shared = Rc::clone(&cx.shared);
let cache = &shared.cache;
@@ -1301,15 +1307,17 @@ fn render_assoc_items_inner(
(RenderMode::Normal, "implementations-list".to_owned(), "")
}
AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
- let id =
- cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
+ let id = cx.derive_id(small_url_encode(format!(
+ "deref-methods-{:#}",
+ type_.print(cx, &at)
+ )));
let derived_id = cx.derive_id(&id);
write_impl_section_heading(
&mut tmp_buf,
&format!(
"Methods from {trait_}<Target = {type_}>",
- trait_ = trait_.print(cx),
- type_ = type_.print(cx),
+ trait_ = trait_.print(cx, &at),
+ type_ = type_.print(cx, &at),
),
&id,
);
@@ -1480,12 +1488,12 @@ pub(crate) fn notable_traits_button(ty: &clean::Type, cx: &mut Context<'_>) -> O
}
}
}
-
if has_notable_trait {
+ let at = AmbiguityTable::empty();
cx.types_with_notable_traits.insert(ty.clone());
Some(format!(
" ⓘ",
- ty = Escape(&format!("{:#}", ty.print(cx))),
+ ty = Escape(&format!("{:#}", ty.print(cx, &at))),
))
} else {
None
@@ -1498,7 +1506,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
let did = ty.def_id(cx.cache()).expect("notable_traits_button already checked this");
let impls = cx.cache().impls.get(&did).expect("notable_traits_button already checked this");
-
+ let at = AmbiguityTable::empty();
for i in impls {
let impl_ = i.inner_impl();
if !ty.is_doc_subtype_of(&impl_.for_, cx.cache()) {
@@ -1515,11 +1523,11 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
&mut out,
"Notable traits for {}
\
",
- impl_.for_.print(cx)
+ impl_.for_.print(cx, &at)
);
}
- write!(&mut out, "{}
", impl_.print(false, cx));
+ write!(&mut out, "{}
", impl_.print(false, cx, &at));
for it in &impl_.items {
if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind {
out.push_str(" ");
@@ -1545,7 +1553,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
out.write_str("");
}
- (format!("{:#}", ty.print(cx)), out.into_inner())
+ (format!("{:#}", ty.print(cx, &at)), out.into_inner())
}
pub(crate) fn notable_traits_json<'a>(
@@ -2016,9 +2024,9 @@ pub(crate) fn render_impl_summary(
"
§\
");
@@ -2144,9 +2152,10 @@ fn get_id_for_impl<'tcx>(tcx: TyCtxt<'tcx>, impl_id: ItemId) -> String {
fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
match *item.kind {
clean::ItemKind::ImplItem(ref i) if i.trait_.is_some() => {
+ let at = AmbiguityTable::empty();
// Alternative format produces no URLs,
// so this parameter does nothing.
- Some((format!("{:#}", i.for_.print(cx)), get_id_for_impl(cx.tcx(), item.item_id)))
+ Some((format!("{:#}", i.for_.print(cx, &at)), get_id_for_impl(cx.tcx(), item.item_id)))
}
_ => None,
}
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 5d4f1acc4b188..b8ab61627f371 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -26,6 +26,7 @@ use crate::clean;
use crate::config::ModuleSorting;
use crate::formats::item_type::ItemType;
use crate::formats::Impl;
+use crate::html::ambiguity::AmbiguityTable;
use crate::html::escape::Escape;
use crate::html::format::{
display_fn, join_with_double_colon, print_abi_with_space, print_constness_with_space,
@@ -172,9 +173,10 @@ fn print_where_clause_and_check<'a, 'tcx: 'a>(
buffer: &mut Buffer,
gens: &'a clean::Generics,
cx: &'a Context<'tcx>,
+ at: &'a AmbiguityTable<'_>,
) -> bool {
let len_before = buffer.len();
- write!(buffer, "{}", print_where_clause(gens, cx, 0, Ending::Newline));
+ write!(buffer, "{}", print_where_clause(gens, cx, at, 0, Ending::Newline));
len_before != buffer.len()
}
@@ -461,6 +463,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
}
clean::ImportItem(ref import) => {
+ let at = AmbiguityTable::empty();
let stab_tags = if let Some(import_def_id) = import.source.did {
// Just need an item with the correct def_id and attrs
let import_item =
@@ -492,7 +495,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
\
{stab_tags_before}{stab_tags}{stab_tags_after}",
vis = visibility_print_with_space(myitem, cx),
- imp = import.print(cx),
+ imp = import.print(cx, &at),
);
w.write_str(ITEM_TABLE_ROW_CLOSE);
}
@@ -633,8 +636,9 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
let asyncness = header.asyncness.print_with_space();
let visibility = visibility_print_with_space(it, cx).to_string();
let name = it.name.unwrap();
+ let at = AmbiguityTable::build_fn(f);
- let generics_len = format!("{:#}", f.generics.print(cx)).len();
+ let generics_len = format!("{:#}", f.generics.print(cx, &at)).len();
let header_len = "fn ".len()
+ visibility.len()
+ constness.len()
@@ -645,7 +649,6 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
+ generics_len;
let notable_traits = notable_traits_button(&f.decl.output, cx);
-
wrap_item(w, |w| {
w.reserve(header_len);
write!(
@@ -659,9 +662,9 @@ fn item_function(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, f: &cle
unsafety = unsafety,
abi = abi,
name = name,
- generics = f.generics.print(cx),
- where_clause = print_where_clause(&f.generics, cx, 0, Ending::Newline),
- decl = f.decl.full_print(header_len, 0, cx),
+ generics = f.generics.print(cx, &at),
+ where_clause = print_where_clause(&f.generics, cx, &at, 0, Ending::Newline),
+ decl = f.decl.full_print(header_len, 0, cx, &at),
notable_traits = notable_traits.unwrap_or_default(),
);
});
@@ -682,6 +685,7 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
let count_methods = required_methods.len() + provided_methods.len();
let must_implement_one_of_functions = tcx.trait_def(t.def_id).must_implement_one_of.clone();
+ let at = AmbiguityTable::empty();
// Output the trait definition
wrap_item(w, |mut w| {
write!(
@@ -692,11 +696,11 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
unsafety = t.unsafety(tcx).print_with_space(),
is_auto = if t.is_auto(tcx) { "auto " } else { "" },
name = it.name.unwrap(),
- generics = t.generics.print(cx),
+ generics = t.generics.print(cx, &at),
);
if !t.generics.where_predicates.is_empty() {
- write!(w, "{}", print_where_clause(&t.generics, cx, 0, Ending::Newline));
+ write!(w, "{}", print_where_clause(&t.generics, cx, &at, 0, Ending::Newline));
} else {
w.write_str(" ");
}
@@ -1185,14 +1189,15 @@ fn item_trait_alias(
it: &clean::Item,
t: &clean::TraitAlias,
) {
+ let at = AmbiguityTable::empty();
wrap_item(w, |w| {
write!(
w,
"{attrs}trait {name}{generics}{where_b} = {bounds};",
attrs = render_attributes_in_pre(it, "", cx),
name = it.name.unwrap(),
- generics = t.generics.print(cx),
- where_b = print_where_clause(&t.generics, cx, 0, Ending::Newline),
+ generics = t.generics.print(cx, &at),
+ where_b = print_where_clause(&t.generics, cx, &at, 0, Ending::Newline),
bounds = bounds(&t.bounds, true, cx),
)
.unwrap();
@@ -1213,14 +1218,15 @@ fn item_opaque_ty(
it: &clean::Item,
t: &clean::OpaqueTy,
) {
+ let at = AmbiguityTable::empty();
wrap_item(w, |w| {
write!(
w,
"{attrs}type {name}{generics}{where_clause} = impl {bounds};",
attrs = render_attributes_in_pre(it, "", cx),
name = it.name.unwrap(),
- generics = t.generics.print(cx),
- where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
+ generics = t.generics.print(cx, &at),
+ where_clause = print_where_clause(&t.generics, cx, &at, 0, Ending::Newline),
bounds = bounds(&t.bounds, false, cx),
)
.unwrap();
@@ -1239,15 +1245,16 @@ fn item_opaque_ty(
fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
wrap_item(w, |w| {
+ let at = AmbiguityTable::empty();
write!(
w,
"{attrs}{vis}type {name}{generics}{where_clause} = {type_};",
attrs = render_attributes_in_pre(it, "", cx),
vis = visibility_print_with_space(it, cx),
name = it.name.unwrap(),
- generics = t.generics.print(cx),
- where_clause = print_where_clause(&t.generics, cx, 0, Ending::Newline),
- type_ = t.type_.print(cx),
+ generics = t.generics.print(cx, &at),
+ where_clause = print_where_clause(&t.generics, cx, &at, 0, Ending::Newline),
+ type_ = t.type_.print(cx, &at),
);
});
}
@@ -1269,8 +1276,8 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
let variants_len = variants.len();
let variants_count = variants_iter().count();
let has_stripped_entries = variants_len != variants_count;
-
- write!(w, "enum {}{}", it.name.unwrap(), t.generics.print(cx));
+ let at = AmbiguityTable::empty();
+ write!(w, "enum {}{}", it.name.unwrap(), t.generics.print(cx, &at));
render_enum_fields(
w,
cx,
@@ -1286,10 +1293,11 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
}
clean::TypeAliasInnerType::Union { fields } => {
wrap_item(w, |w| {
+ let at = AmbiguityTable::empty();
let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
let has_stripped_fields = fields.len() != fields_count;
- write!(w, "union {}{}", it.name.unwrap(), t.generics.print(cx));
+ write!(w, "union {}{}", it.name.unwrap(), t.generics.print(cx, &at));
render_struct_fields(
w,
Some(&t.generics),
@@ -1305,10 +1313,11 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
}
clean::TypeAliasInnerType::Struct { ctor_kind, fields } => {
wrap_item(w, |w| {
+ let at = AmbiguityTable::empty();
let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
let has_stripped_fields = fields.len() != fields_count;
- write!(w, "struct {}{}", it.name.unwrap(), t.generics.print(cx));
+ write!(w, "struct {}{}", it.name.unwrap(), t.generics.print(cx, &at));
render_struct_fields(
w,
Some(&t.generics),
@@ -1471,8 +1480,9 @@ fn item_union(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean:
ty: &'a clean::Type,
) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
display_fn(move |f| {
+ let at = AmbiguityTable::empty();
let cx = self.cx.borrow();
- let v = ty.print(*cx);
+ let v = ty.print(*cx, &at);
write!(f, "{v}")
})
}
@@ -1513,7 +1523,10 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>(
}
match *ty.kind {
clean::StrippedItem(box clean::StructFieldItem(_)) => f.write_str("_")?,
- clean::StructFieldItem(ref ty) => write!(f, "{}", ty.print(cx))?,
+ clean::StructFieldItem(ref ty) => {
+ let at = AmbiguityTable::empty();
+ write!(f, "{}", ty.print(cx, &at))?;
+ }
_ => unreachable!(),
}
}
@@ -1525,12 +1538,13 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
let count_variants = e.variants().count();
wrap_item(w, |w| {
render_attributes_in_code(w, it, cx);
+ let at = AmbiguityTable::empty();
write!(
w,
"{}enum {}{}",
visibility_print_with_space(it, cx),
it.name.unwrap(),
- e.generics.print(cx),
+ e.generics.print(cx, &at),
);
render_enum_fields(
@@ -1616,7 +1630,8 @@ fn render_enum_fields(
enum_def_id: DefId,
) {
let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants);
- if !g.is_some_and(|g| print_where_clause_and_check(w, g, cx)) {
+ let at = AmbiguityTable::empty();
+ if !g.is_some_and(|g| print_where_clause_and_check(w, g, cx, &at)) {
// If there wasn't a `where` clause, we add a whitespace.
w.write_str(" ");
}
@@ -1759,6 +1774,7 @@ fn item_variants(
{}",
document_non_exhaustive(variant)
);
+ let at = AmbiguityTable::empty();
for field in fields {
match *field.kind {
clean::StrippedItem(box clean::StructFieldItem(_)) => {}
@@ -1776,7 +1792,7 @@ fn item_variants(
{f}: {t}
\
",
f = field.name.unwrap(),
- t = ty.print(cx),
+ t = ty.print(cx, &at),
);
write!(
w,
@@ -1855,15 +1871,15 @@ fn item_constant(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, c: &cle
wrap_item(w, |w| {
let tcx = cx.tcx();
render_attributes_in_code(w, it, cx);
-
+ let at = AmbiguityTable::empty();
write!(
w,
"{vis}const {name}{generics}: {typ}{where_clause}",
vis = visibility_print_with_space(it, cx),
name = it.name.unwrap(),
- generics = c.generics.print(cx),
- typ = c.type_.print(cx),
- where_clause = print_where_clause(&c.generics, cx, 0, Ending::NoNewline),
+ generics = c.generics.print(cx, &at),
+ typ = c.type_.print(cx, &at),
+ where_clause = print_where_clause(&c.generics, cx, &at, 0, Ending::NoNewline),
);
// FIXME: The code below now prints
@@ -1938,6 +1954,7 @@ fn item_fields(
document_non_exhaustive_header(it),
);
write_section_heading(w, &title, "fields", Some("fields"), document_non_exhaustive(it));
+ let at = AmbiguityTable::empty();
for (index, (field, ty)) in fields.enumerate() {
let field_name =
field.name.map_or_else(|| index.to_string(), |sym| sym.as_str().to_string());
@@ -1949,7 +1966,7 @@ fn item_fields(
{field_name}: {ty}
\
",
item_type = ItemType::StructField,
- ty = ty.print(cx)
+ ty = ty.print(cx, &at)
);
write!(w, "{}", document(cx, field, Some(it), HeadingOffset::H3));
}
@@ -1960,13 +1977,14 @@ fn item_fields(
fn item_static(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Static) {
wrap_item(w, |buffer| {
render_attributes_in_code(buffer, it, cx);
+ let at = AmbiguityTable::empty();
write!(
buffer,
"{vis}static {mutability}{name}: {typ}",
vis = visibility_print_with_space(it, cx),
mutability = s.mutability.print_with_space(),
name = it.name.unwrap(),
- typ = s.type_.print(cx)
+ typ = s.type_.print(cx, &at)
)
.unwrap();
});
@@ -2049,6 +2067,7 @@ pub(super) fn item_path(ty: ItemType, name: &str) -> String {
fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) -> String {
let mut bounds = String::new();
+ let at = AmbiguityTable::empty();
if !t_bounds.is_empty() {
if !trait_alias {
bounds.push_str(": ");
@@ -2057,7 +2076,7 @@ fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>)
if i > 0 {
bounds.push_str(" + ");
}
- bounds.push_str(&p.print(cx).to_string());
+ bounds.push_str(&p.print(cx, &at).to_string());
}
}
bounds
@@ -2078,7 +2097,8 @@ struct ImplString(String);
impl ImplString {
fn new(i: &Impl, cx: &Context<'_>) -> ImplString {
- ImplString(format!("{}", i.inner_impl().print(false, cx)))
+ let at = AmbiguityTable::empty();
+ ImplString(format!("{}", i.inner_impl().print(false, cx, &at)))
}
}
@@ -2139,12 +2159,12 @@ fn render_union<'a, 'cx: 'a>(
) -> impl fmt::Display + 'a + Captures<'cx> {
display_fn(move |mut f| {
write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?;
-
+ let at = AmbiguityTable::empty();
let where_displayed = g
.map(|g| {
let mut buf = Buffer::html();
- write!(buf, "{}", g.print(cx));
- let where_displayed = print_where_clause_and_check(&mut buf, g, cx);
+ write!(buf, "{}", g.print(cx, &at));
+ let where_displayed = print_where_clause_and_check(&mut buf, g, cx, &at);
write!(f, "{buf}", buf = buf.into_inner()).unwrap();
where_displayed
})
@@ -2170,7 +2190,7 @@ fn render_union<'a, 'cx: 'a>(
" {}{}: {},\n",
visibility_print_with_space(field, cx),
field.name.unwrap(),
- ty.print(cx)
+ ty.print(cx, &at)
)?;
}
}
@@ -2204,7 +2224,8 @@ fn render_struct(
it.name.unwrap()
);
if let Some(g) = g {
- write!(w, "{}", g.print(cx))
+ let at = AmbiguityTable::empty();
+ write!(w, "{}", g.print(cx, &at));
}
render_struct_fields(
w,
@@ -2228,10 +2249,11 @@ fn render_struct_fields(
has_stripped_entries: bool,
cx: &Context<'_>,
) {
+ let at = AmbiguityTable::empty();
match ty {
None => {
let where_displayed =
- g.map(|g| print_where_clause_and_check(w, g, cx)).unwrap_or(false);
+ g.map(|g| print_where_clause_and_check(w, g, cx, &at)).unwrap_or(false);
// If there wasn't a `where` clause, we add a whitespace.
if !where_displayed {
@@ -2253,7 +2275,7 @@ fn render_struct_fields(
"\n{tab} {vis}{name}: {ty},",
vis = visibility_print_with_space(field, cx),
name = field.name.unwrap(),
- ty = ty.print(cx),
+ ty = ty.print(cx, &at),
);
}
}
@@ -2287,7 +2309,12 @@ fn render_struct_fields(
match *field.kind {
clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"),
clean::StructFieldItem(ref ty) => {
- write!(w, "{}{}", visibility_print_with_space(field, cx), ty.print(cx),)
+ write!(
+ w,
+ "{}{}",
+ visibility_print_with_space(field, cx),
+ ty.print(cx, &at),
+ )
}
_ => unreachable!(),
}
@@ -2295,7 +2322,7 @@ fn render_struct_fields(
}
w.write_str(")");
if let Some(g) = g {
- write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline));
+ write!(w, "{}", print_where_clause(g, cx, &at, 0, Ending::NoNewline));
}
// We only want a ";" when we are displaying a tuple struct, not a variant tuple struct.
if structhead {
@@ -2305,7 +2332,7 @@ fn render_struct_fields(
Some(CtorKind::Const) => {
// Needed for PhantomData.
if let Some(g) = g {
- write!(w, "{}", print_where_clause(g, cx, 0, Ending::NoNewline));
+ write!(w, "{}", print_where_clause(g, cx, &at, 0, Ending::NoNewline));
}
w.write_str(";");
}
diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs
index 3d28937eb99e1..f45addfc37da0 100644
--- a/src/librustdoc/html/render/sidebar.rs
+++ b/src/librustdoc/html/render/sidebar.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::{self, TyCtxt};
use crate::{
clean,
formats::{item_type::ItemType, Impl},
- html::{format::Buffer, markdown::IdMap},
+ html::{ambiguity::AmbiguityTable, format::Buffer, markdown::IdMap},
};
use super::{item_ty_to_section, Context, ItemSection};
@@ -423,10 +423,11 @@ fn sidebar_deref_methods<'a>(
} else {
Cow::Borrowed("deref-methods")
};
+ let at = AmbiguityTable::empty();
let title = format!(
"Methods from {:#}",
- impl_.inner_impl().trait_.as_ref().unwrap().print(cx),
- real_target.print(cx),
+ impl_.inner_impl().trait_.as_ref().unwrap().print(cx, &at),
+ real_target.print(cx, &at),
);
// We want links' order to be reproducible so we don't use unstable sort.
ret.sort();
@@ -530,7 +531,8 @@ fn sidebar_render_assoc_items(
ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
ty::ImplPolarity::Negative => "!",
};
- let generated = Link::new(encoded, format!("{prefix}{:#}", trait_.print(cx)));
+ let at = AmbiguityTable::empty();
+ let generated = Link::new(encoded, format!("{prefix}{:#}", trait_.print(cx, &at)));
if links.insert(generated.clone()) { Some(generated) } else { None }
})
.collect::>>();
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index fbd45b2b48ef9..82b0316735b4e 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -23,6 +23,7 @@ use crate::error::Error;
use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
use crate::formats::Impl;
+use crate::html::ambiguity::AmbiguityTable;
use crate::html::format::Buffer;
use crate::html::render::{AssocItemLink, ImplRenderingParameters};
use crate::html::{layout, static_files};
@@ -534,11 +535,12 @@ else if (window.initSearch) window.initSearch(searchIndex);
.values()
.flat_map(|AliasedTypeImpl { impl_, type_aliases }| {
let mut ret = Vec::new();
+ let at = AmbiguityTable::empty();
let trait_ = impl_
.inner_impl()
.trait_
.as_ref()
- .map(|trait_| format!("{:#}", trait_.print(cx)));
+ .map(|trait_| format!("{:#}", trait_.print(cx, &at)));
// render_impl will filter out "impossible-to-call" methods
// to make that functionality work here, it needs to be called with
// each type alias, and if it gives a different result, split the impl
@@ -692,8 +694,10 @@ else if (window.initSearch) window.initSearch(searchIndex);
if imp.impl_item.item_id.krate() == did.krate || !imp.impl_item.item_id.is_local() {
None
} else {
+ let at = AmbiguityTable::empty();
+ let text = imp.inner_impl().print(false, cx, &at).to_string();
Some(Implementor {
- text: imp.inner_impl().print(false, cx).to_string(),
+ text,
synthetic: imp.inner_impl().kind.is_auto(),
types: collect_paths_for_type(imp.inner_impl().for_.clone(), cache),
})
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 18651875130fc..b270dc0f42a99 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -10,6 +10,7 @@
#![feature(iter_intersperse)]
#![feature(lazy_cell)]
#![feature(let_chains)]
+#![feature(map_entry_replace)]
#![feature(never_type)]
#![feature(round_char_boundary)]
#![feature(test)]
diff --git a/tests/rustdoc/fn_param_ambiguities.rs b/tests/rustdoc/fn_param_ambiguities.rs
new file mode 100644
index 0000000000000..ba35b6471cc12
--- /dev/null
+++ b/tests/rustdoc/fn_param_ambiguities.rs
@@ -0,0 +1,13 @@
+pub mod X {
+ pub enum A {}
+ pub enum B {}
+ pub enum C {}
+}
+
+pub mod Y {
+ pub enum A {}
+ pub enum B {}
+}
+
+// @has fn_param_ambiguities/fn.f.html //pre 'pub fn f(xa: X::A, ya: Y::A, yb: B, xc: C)'
+pub fn f(xa: X::A, ya: Y::A, yb : Y::B, xc: X::C) {}