diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b9d7acee63c..e08318e4f54 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -521,7 +521,7 @@ fn clean_generic_param_def<'tcx>( }, ) } - ty::GenericParamDefKind::Const { has_default, .. } => ( + ty::GenericParamDefKind::Const { has_default, is_host_effect } => ( def.name, GenericParamDefKind::Const { ty: Box::new(clean_middle_ty( @@ -541,6 +541,7 @@ fn clean_generic_param_def<'tcx>( )), false => None, }, + is_host_effect, }, ), }; @@ -597,6 +598,7 @@ fn clean_generic_param<'tcx>( ty: Box::new(clean_ty(ty, cx)), default: default .map(|ct| Box::new(ty::Const::from_anon_const(cx.tcx, ct.def_id).to_string())), + is_host_effect: cx.tcx.has_attr(param.def_id, sym::rustc_host), }, ), }; @@ -2508,14 +2510,22 @@ fn clean_generic_args<'tcx>( let args = generic_args .args .iter() - .map(|arg| match arg { - hir::GenericArg::Lifetime(lt) if !lt.is_anonymous() => { - GenericArg::Lifetime(clean_lifetime(*lt, cx)) - } - hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), - hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)), - hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))), - hir::GenericArg::Infer(_inf) => GenericArg::Infer, + .filter_map(|arg| { + Some(match arg { + hir::GenericArg::Lifetime(lt) if !lt.is_anonymous() => { + GenericArg::Lifetime(clean_lifetime(*lt, cx)) + } + hir::GenericArg::Lifetime(_) => GenericArg::Lifetime(Lifetime::elided()), + hir::GenericArg::Type(ty) => GenericArg::Type(clean_ty(ty, cx)), + // FIXME(effects): This will still emit `` for non-const impls of const traits + hir::GenericArg::Const(ct) + if cx.tcx.has_attr(ct.value.def_id, sym::rustc_host) => + { + return None; + } + hir::GenericArg::Const(ct) => GenericArg::Const(Box::new(clean_const(ct, cx))), + hir::GenericArg::Infer(_inf) => GenericArg::Infer, + }) }) .collect::>() .into(); diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 48ce0a89449..517a51867cf 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1306,7 +1306,7 @@ pub(crate) fn get_bounds(&self) -> Option<&[GenericBound]> { pub(crate) enum GenericParamDefKind { Lifetime { outlives: Vec }, Type { did: DefId, bounds: Vec, default: Option>, synthetic: bool }, - Const { ty: Box, default: Option> }, + Const { ty: Box, default: Option>, is_host_effect: bool }, } impl GenericParamDefKind { @@ -1326,9 +1326,10 @@ pub(crate) fn lifetime(name: Symbol) -> Self { Self { name, kind: GenericParamDefKind::Lifetime { outlives: Vec::new() } } } - pub(crate) fn is_synthetic_type_param(&self) -> bool { + pub(crate) fn is_synthetic_param(&self) -> bool { match self.kind { - GenericParamDefKind::Lifetime { .. } | GenericParamDefKind::Const { .. } => false, + GenericParamDefKind::Lifetime { .. } => false, + GenericParamDefKind::Const { is_host_effect, .. } => is_host_effect, GenericParamDefKind::Type { synthetic, .. } => synthetic, } } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 01078504b71..c5302570489 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -104,6 +104,10 @@ pub(crate) fn ty_args_to_args<'tcx>( arg: index, }), ))), + // FIXME(effects): this relies on the host effect being called `host`, which users could also name + // their const generics. + // FIXME(effects): this causes `host = true` and `host = false` generics to also be emitted. + GenericArgKind::Const(ct) if let ty::ConstKind::Param(p) = ct.kind() && p.name == sym::host => None, GenericArgKind::Const(ct) => { Some(GenericArg::Const(Box::new(clean_middle_const(kind.rebind(ct), cx)))) } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1983bb11e5b..aa3f7184b4e 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -250,8 +250,7 @@ pub(crate) fn print<'a, 'tcx: 'a>( cx: &'a Context<'tcx>, ) -> impl fmt::Display + 'a + Captures<'tcx> { display_fn(move |f| { - let mut real_params = - self.params.iter().filter(|p| !p.is_synthetic_type_param()).peekable(); + let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable(); if real_params.peek().is_none() { return Ok(()); } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index e7f782bb6a6..1420d108664 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -453,7 +453,7 @@ fn from_tcx(kind: clean::GenericParamDefKind, tcx: TyCtxt<'_>) -> Self { default: default.map(|x| (*x).into_tcx(tcx)), synthetic, }, - Const { ty, default } => GenericParamDefKind::Const { + Const { ty, default, is_host_effect: _ } => GenericParamDefKind::Const { type_: (*ty).into_tcx(tcx), default: default.map(|x| *x), }, @@ -491,12 +491,14 @@ fn from_tcx(predicate: clean::WherePredicate, tcx: TyCtxt<'_>) -> Self { default: default.map(|ty| (*ty).into_tcx(tcx)), synthetic, }, - clean::GenericParamDefKind::Const { ty, default } => { - GenericParamDefKind::Const { - type_: (*ty).into_tcx(tcx), - default: default.map(|d| *d), - } - } + clean::GenericParamDefKind::Const { + ty, + default, + is_host_effect: _, + } => GenericParamDefKind::Const { + type_: (*ty).into_tcx(tcx), + default: default.map(|d| *d), + }, }; GenericParamDef { name, kind } }) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index fc2acb6eaa3..67f5ea5d98b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -6,6 +6,7 @@ #![feature(array_methods)] #![feature(assert_matches)] #![feature(box_patterns)] +#![feature(if_let_guard)] #![feature(impl_trait_in_assoc_type)] #![feature(iter_intersperse)] #![feature(lazy_cell)] diff --git a/tests/rustdoc/const-effect-param.rs b/tests/rustdoc/const-effect-param.rs new file mode 100644 index 00000000000..f50a9b96d81 --- /dev/null +++ b/tests/rustdoc/const-effect-param.rs @@ -0,0 +1,12 @@ +#![crate_name = "foo"] +#![feature(effects, const_trait_impl)] + +#[const_trait] +pub trait Tr { + fn f(); +} + +// @has foo/fn.g.html +// @has - '//pre[@class="rust item-decl"]' 'pub const fn g()' +/// foo +pub const fn g() {} diff --git a/tests/rustdoc/const-fn-effects.rs b/tests/rustdoc/const-fn-effects.rs new file mode 100644 index 00000000000..7c19b4b2c0c --- /dev/null +++ b/tests/rustdoc/const-fn-effects.rs @@ -0,0 +1,19 @@ +#![crate_name = "foo"] +#![feature(effects)] + +// @has foo/fn.bar.html +// @has - '//pre[@class="rust item-decl"]' 'pub const fn bar() -> ' +/// foo +pub const fn bar() -> usize { + 2 +} + +// @has foo/struct.Foo.html +// @has - '//*[@class="method"]' 'const fn new()' +pub struct Foo(usize); + +impl Foo { + pub const fn new() -> Foo { + Foo(0) + } +} diff --git a/tests/rustdoc/inline_cross/auxiliary/const-fn.rs b/tests/rustdoc/inline_cross/auxiliary/const-fn.rs new file mode 100644 index 00000000000..26332b419b6 --- /dev/null +++ b/tests/rustdoc/inline_cross/auxiliary/const-fn.rs @@ -0,0 +1,5 @@ +#![feature(effects)] + +pub const fn load() -> i32 { + 0 +} diff --git a/tests/rustdoc/inline_cross/const-fn.rs b/tests/rustdoc/inline_cross/const-fn.rs new file mode 100644 index 00000000000..24934b873c2 --- /dev/null +++ b/tests/rustdoc/inline_cross/const-fn.rs @@ -0,0 +1,10 @@ +// Regression test for issue #116629. +// Check that we render the correct generic params of const fn + +// aux-crate:const_fn=const-fn.rs +// edition: 2021 +#![crate_name = "user"] + +// @has user/fn.load.html +// @has - '//pre[@class="rust item-decl"]' "pub const fn load() -> i32" +pub use const_fn::load;