Skip to content

Remove clean::Function::header and calculate it on-demand #91217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,20 +223,12 @@ crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Tra

fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Function {
let sig = cx.tcx.fn_sig(did);

let constness =
if cx.tcx.is_const_fn_raw(did) { hir::Constness::Const } else { hir::Constness::NotConst };
let asyncness = cx.tcx.asyncness(did);
let predicates = cx.tcx.predicates_of(did);
let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
// NOTE: generics need to be cleaned before the decl!
((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx))
});
clean::Function {
decl,
generics,
header: hir::FnHeader { unsafety: sig.unsafety(), abi: sig.abi(), constness, asyncness },
}
clean::Function { decl, generics }
}

fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
Expand Down
82 changes: 8 additions & 74 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ crate mod utils;

use rustc_ast as ast;
use rustc_attr as attr;
use rustc_const_eval::const_eval::is_unstable_const_fn;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
Expand All @@ -25,8 +24,6 @@ use rustc_middle::{bug, span_bug};
use rustc_span::hygiene::{AstPass, MacroKind};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{self, ExpnKind};
use rustc_target::spec::abi::Abi;
use rustc_typeck::check::intrinsic::intrinsic_operation_unsafety;
use rustc_typeck::hir_ty_to_ty;

use std::assert_matches::assert_matches;
Expand Down Expand Up @@ -747,14 +744,7 @@ fn clean_fn_or_proc_macro(
ProcMacroItem(ProcMacro { kind, helpers })
}
None => {
let mut func = (sig, generics, body_id).clean(cx);
let def_id = item.def_id.to_def_id();
func.header.constness =
if cx.tcx.is_const_fn(def_id) && is_unstable_const_fn(cx.tcx, def_id).is_none() {
hir::Constness::Const
} else {
hir::Constness::NotConst
};
let func = (sig, generics, body_id).clean(cx);
FunctionItem(func)
}
}
Expand All @@ -769,7 +759,7 @@ impl<'a> Clean<Function> for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::Bo
let decl = clean_fn_decl_with_args(cx, self.0.decl, args);
(generics, decl)
});
Function { decl, generics, header: self.0.header }
Function { decl, generics }
}
}

Expand Down Expand Up @@ -885,12 +875,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx.tcx, e)))
}
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
let mut m = (sig, &self.generics, body).clean(cx);
if m.header.constness == hir::Constness::Const
&& is_unstable_const_fn(cx.tcx, local_did).is_some()
{
m.header.constness = hir::Constness::NotConst;
}
let m = (sig, &self.generics, body).clean(cx);
MethodItem(m, None)
}
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => {
Expand All @@ -901,12 +886,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
let decl = clean_fn_decl_with_args(cx, sig.decl, args);
(generics, decl)
});
let mut t = Function { header: sig.header, decl, generics };
if t.header.constness == hir::Constness::Const
&& is_unstable_const_fn(cx.tcx, local_did).is_some()
{
t.header.constness = hir::Constness::NotConst;
}
let t = Function { decl, generics };
TyMethodItem(t)
}
hir::TraitItemKind::Type(bounds, ref default) => {
Expand All @@ -932,12 +912,7 @@ impl Clean<Item> for hir::ImplItem<'_> {
AssocConstItem(ty.clean(cx), Some(print_const_expr(cx.tcx, expr)))
}
hir::ImplItemKind::Fn(ref sig, body) => {
let mut m = (sig, &self.generics, body).clean(cx);
if m.header.constness == hir::Constness::Const
&& is_unstable_const_fn(cx.tcx, local_did).is_some()
{
m.header.constness = hir::Constness::NotConst;
}
let m = (sig, &self.generics, body).clean(cx);
MethodItem(m, Some(self.defaultness))
}
hir::ImplItemKind::TyAlias(ref hir_ty) => {
Expand Down Expand Up @@ -1017,40 +992,13 @@ impl Clean<Item> for ty::AssocItem {
ty::TraitContainer(_) => self.defaultness.has_value(),
};
if provided {
let constness = if tcx.is_const_fn_raw(self.def_id) {
hir::Constness::Const
} else {
hir::Constness::NotConst
};
let asyncness = tcx.asyncness(self.def_id);
let defaultness = match self.container {
ty::ImplContainer(_) => Some(self.defaultness),
ty::TraitContainer(_) => None,
};
MethodItem(
Function {
generics,
decl,
header: hir::FnHeader {
unsafety: sig.unsafety(),
abi: sig.abi(),
constness,
asyncness,
},
},
defaultness,
)
MethodItem(Function { generics, decl }, defaultness)
} else {
TyMethodItem(Function {
generics,
decl,
header: hir::FnHeader {
unsafety: sig.unsafety(),
abi: sig.abi(),
constness: hir::Constness::NotConst,
asyncness: hir::IsAsync::NotAsync,
},
})
TyMethodItem(Function { generics, decl })
}
}
ty::AssocKind::Type => {
Expand Down Expand Up @@ -2020,28 +1968,14 @@ impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
cx.with_param_env(def_id, |cx| {
let kind = match item.kind {
hir::ForeignItemKind::Fn(decl, names, ref generics) => {
let abi = cx.tcx.hir().get_foreign_abi(item.hir_id());
let (generics, decl) = enter_impl_trait(cx, |cx| {
// NOTE: generics must be cleaned before args
let generics = generics.clean(cx);
let args = (decl.inputs, names).clean(cx);
let decl = clean_fn_decl_with_args(cx, decl, args);
(generics, decl)
});
ForeignFunctionItem(Function {
decl,
generics,
header: hir::FnHeader {
unsafety: if abi == Abi::RustIntrinsic {
intrinsic_operation_unsafety(item.ident.name)
} else {
hir::Unsafety::Unsafe
},
abi,
constness: hir::Constness::NotConst,
asyncness: hir::IsAsync::NotAsync,
},
})
ForeignFunctionItem(Function { decl, generics })
}
hir::ForeignItemKind::Static(ref ty, mutability) => {
ForeignStaticItem(Static { type_: ty.clean(cx), mutability, expr: None })
Expand Down
1 change: 0 additions & 1 deletion src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1303,7 +1303,6 @@ crate struct Generics {
crate struct Function {
crate decl: FnDecl,
crate generics: Generics,
crate header: hir::FnHeader,
}

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
Expand Down
28 changes: 15 additions & 13 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -873,14 +873,21 @@ fn render_assoc_item(
fn method(
w: &mut Buffer,
meth: &clean::Item,
header: hir::FnHeader,
g: &clean::Generics,
d: &clean::FnDecl,
link: AssocItemLink<'_>,
parent: ItemType,
cx: &Context<'_>,
) {
let tcx = cx.tcx();
let name = meth.name.as_ref().unwrap();
let did = meth.def_id.expect_def_id();
let sig = tcx.fn_sig(did);
let meth_constness =
if tcx.is_const_fn_raw(did) { hir::Constness::Const } else { hir::Constness::NotConst };
let meth_asyncness = tcx.asyncness(did);
let meth_unsafety = sig.unsafety();

let href = match link {
AssocItemLink::Anchor(Some(ref id)) => Some(format!("#{}", id)),
AssocItemLink::Anchor(None) => Some(format!("#{}.{}", meth.type_(), name)),
Expand All @@ -901,12 +908,11 @@ fn render_assoc_item(
}
};
let vis = meth.visibility.print_with_space(meth.def_id, cx).to_string();
let constness =
print_constness_with_space(&header.constness, meth.const_stability(cx.tcx()));
let asyncness = header.asyncness.print_with_space();
let unsafety = header.unsafety.print_with_space();
let constness = print_constness_with_space(&meth_constness, meth.const_stability(tcx));
let asyncness = meth_asyncness.print_with_space();
let unsafety = meth_unsafety.print_with_space();
let defaultness = print_default_space(meth.is_default());
let abi = print_abi_with_space(header.abi).to_string();
let abi = print_abi_with_space(sig.abi()).to_string();

// 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();
Expand Down Expand Up @@ -945,19 +951,15 @@ fn render_assoc_item(
href = href.map(|href| format!("href=\"{}\"", href)).unwrap_or_else(|| "".to_string()),
name = name,
generics = g.print(cx),
decl = d.full_print(header_len, indent, header.asyncness, cx),
decl = d.full_print(header_len, indent, meth_asyncness, cx),
notable_traits = notable_traits_decl(d, cx),
where_clause = print_where_clause(g, cx, indent, end_newline),
)
}
match *item.kind {
clean::StrippedItem(..) => {}
clean::TyMethodItem(ref m) => {
method(w, item, m.header, &m.generics, &m.decl, link, parent, cx)
}
clean::MethodItem(ref m, _) => {
method(w, item, m.header, &m.generics, &m.decl, link, parent, cx)
}
clean::TyMethodItem(ref m) => method(w, item, &m.generics, &m.decl, link, parent, cx),
clean::MethodItem(ref m, _) => method(w, item, &m.generics, &m.decl, link, parent, cx),
clean::AssocConstItem(ref ty, ref default) => assoc_const(
w,
item,
Expand Down
23 changes: 16 additions & 7 deletions src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,9 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
}

let unsafety_flag = match *myitem.kind {
clean::FunctionItem(ref func) | clean::ForeignFunctionItem(ref func)
if func.header.unsafety == hir::Unsafety::Unsafe =>
clean::FunctionItem(_) | clean::ForeignFunctionItem(_)
if cx.tcx().fn_sig(myitem.def_id.expect_def_id()).unsafety()
== hir::Unsafety::Unsafe =>
{
"<a title=\"unsafe function\" href=\"#\"><sup>⚠</sup></a>"
}
Expand Down Expand Up @@ -465,11 +466,19 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) ->
}

fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
let tcx = cx.tcx();
let did = it.def_id.expect_def_id();
let sig = tcx.fn_sig(did);
let it_constness =
if tcx.is_const_fn_raw(did) { hir::Constness::Const } else { hir::Constness::NotConst };
let it_asyncness = tcx.asyncness(did);
let it_unsafety = sig.unsafety();

let vis = it.visibility.print_with_space(it.def_id, cx).to_string();
let constness = print_constness_with_space(&f.header.constness, it.const_stability(cx.tcx()));
let asyncness = f.header.asyncness.print_with_space();
let unsafety = f.header.unsafety.print_with_space();
let abi = print_abi_with_space(f.header.abi).to_string();
let constness = print_constness_with_space(&it_constness, it.const_stability(tcx));
let asyncness = it_asyncness.print_with_space();
let unsafety = it_unsafety.print_with_space();
let abi = print_abi_with_space(sig.abi()).to_string();
let name = it.name.as_ref().unwrap();

let generics_len = format!("{:#}", f.generics.print(cx)).len();
Expand Down Expand Up @@ -498,7 +507,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
name = name,
generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx, 0, true),
decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
decl = f.decl.full_print(header_len, 0, it_asyncness, cx),
notable_traits = notable_traits_decl(&f.decl, cx),
);
});
Expand Down
66 changes: 52 additions & 14 deletions src/librustdoc/json/conversions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,12 +203,18 @@ fn from_clean_item(item: clean::Item, tcx: TyCtxt<'_>) -> ItemEnum {
StructFieldItem(f) => ItemEnum::StructField(f.into_tcx(tcx)),
EnumItem(e) => ItemEnum::Enum(e.into_tcx(tcx)),
VariantItem(v) => ItemEnum::Variant(v.into_tcx(tcx)),
FunctionItem(f) => ItemEnum::Function(f.into_tcx(tcx)),
ForeignFunctionItem(f) => ItemEnum::Function(f.into_tcx(tcx)),
FunctionItem(f) => ItemEnum::Function(from_function(f, item.def_id.expect_def_id(), tcx)),
ForeignFunctionItem(f) => {
ItemEnum::Function(from_function(f, item.def_id.expect_def_id(), tcx))
}
TraitItem(t) => ItemEnum::Trait(t.into_tcx(tcx)),
TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_tcx(tcx)),
MethodItem(m, _) => ItemEnum::Method(from_function_method(m, true, tcx)),
TyMethodItem(m) => ItemEnum::Method(from_function_method(m, false, tcx)),
MethodItem(m, _) => {
ItemEnum::Method(from_function_method(m, item.def_id.expect_def_id(), true, tcx))
}
TyMethodItem(m) => {
ItemEnum::Method(from_function_method(m, item.def_id.expect_def_id(), false, tcx))
}
ImplItem(i) => ItemEnum::Impl(i.into_tcx(tcx)),
StaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
ForeignStaticItem(s) => ItemEnum::Static(s.into_tcx(tcx)),
Expand Down Expand Up @@ -287,18 +293,39 @@ crate fn from_fn_header(header: &rustc_hir::FnHeader) -> HashSet<Qualifiers> {
v
}

impl FromWithTcx<clean::Function> for Function {
fn from_tcx(function: clean::Function, tcx: TyCtxt<'_>) -> Self {
let clean::Function { decl, generics, header } = function;
Function {
decl: decl.into_tcx(tcx),
generics: generics.into_tcx(tcx),
header: from_fn_header(&header),
abi: header.abi.to_string(),
}
crate fn from_function(function: clean::Function, did: DefId, tcx: TyCtxt<'_>) -> Function {
let clean::Function { decl, generics } = function;
let sig = tcx.fn_sig(did);
let constness = if tcx.is_const_fn_raw(did) {
rustc_hir::Constness::Const
} else {
rustc_hir::Constness::NotConst
};
let asyncness = tcx.asyncness(did);
let header =
rustc_hir::FnHeader { unsafety: sig.unsafety(), abi: sig.abi(), constness, asyncness };

Function {
decl: decl.into_tcx(tcx),
generics: generics.into_tcx(tcx),
header: from_fn_header(&header),
abi: header.abi.to_string(),
}
}

// impl FromWithTcx<clean::Function> for Function {
// fn from_tcx(function: clean::Function, tcx: TyCtxt<'_>) -> Self {
// let clean::Function { decl, generics } = function;
// let header = hir::FnHeader { unsafety: sig.unsafety(), abi: sig.abi(), constness, asyncness }
// Function {
// decl: decl.into_tcx(tcx),
// generics: generics.into_tcx(tcx),
// header: from_fn_header(&header),
// abi: header.abi.to_string(),
// }
// }
// }

impl FromWithTcx<clean::Generics> for Generics {
fn from_tcx(generics: clean::Generics, tcx: TyCtxt<'_>) -> Self {
Generics {
Expand Down Expand Up @@ -535,10 +562,21 @@ impl FromWithTcx<clean::Impl> for Impl {

crate fn from_function_method(
function: clean::Function,
did: DefId,
has_body: bool,
tcx: TyCtxt<'_>,
) -> Method {
let clean::Function { header, decl, generics } = function;
let clean::Function { decl, generics } = function;
let sig = tcx.fn_sig(did);
let constness = if tcx.is_const_fn_raw(did) {
rustc_hir::Constness::Const
} else {
rustc_hir::Constness::NotConst
};
let asyncness = tcx.asyncness(did);
let header =
rustc_hir::FnHeader { unsafety: sig.unsafety(), abi: sig.abi(), constness, asyncness };

Method {
decl: decl.into_tcx(tcx),
generics: generics.into_tcx(tcx),
Expand Down
1 change: 0 additions & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ extern crate rustc_ast;
extern crate rustc_ast_lowering;
extern crate rustc_ast_pretty;
extern crate rustc_attr;
extern crate rustc_const_eval;
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_errors;
Expand Down