From fa93dbdeaeff50f2a4e5eaec329b62941b602d85 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Sat, 3 Jan 2026 00:18:03 +0200 Subject: [PATCH 1/3] [rustdoc] Don't try to print the value of a non-primitive const --- src/librustdoc/clean/utils.rs | 3 +++ .../non-primitive-assoc-const-150312.rs | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 tests/rustdoc-html/non-primitive-assoc-const-150312.rs diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 0f75a332ad6bc..e687378a501ac 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -371,6 +371,9 @@ pub(crate) fn print_evaluated_const( ) -> Option { tcx.const_eval_poly(def_id).ok().and_then(|val| { let ty = tcx.type_of(def_id).instantiate_identity(); + if !ty.is_primitive() { + return None; + } match (val, ty.kind()) { (_, &ty::Ref(..)) => None, (mir::ConstValue::Scalar(_), &ty::Adt(_, _)) => None, diff --git a/tests/rustdoc-html/non-primitive-assoc-const-150312.rs b/tests/rustdoc-html/non-primitive-assoc-const-150312.rs new file mode 100644 index 0000000000000..cf6deaed024b4 --- /dev/null +++ b/tests/rustdoc-html/non-primitive-assoc-const-150312.rs @@ -0,0 +1,18 @@ +#![crate_name = "foo"] + +pub trait Foo { + type AssocType; + + const THE_CONST: Self::AssocType; +} + +pub struct Bar; + +impl Foo for Bar { + type AssocType = (u32,); + + //@ has foo/struct.Bar.html + //@ matches - '//section[@id="associatedconstant.THE_CONST"]/h4[@class="code-header"]' '^const THE_CONST: Self::AssocType' + //@ !matches - '//section[@id="associatedconstant.THE_CONST"]//*[last()]' '{transmute' + const THE_CONST: Self::AssocType = (1u32,); +} From fe10b2243c2efea6a7bf403a5518fb72ad046163 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Mon, 5 Jan 2026 00:06:38 +0200 Subject: [PATCH 2/3] wip --- src/librustdoc/clean/utils.rs | 23 +++++------ src/librustdoc/html/render/print_item.rs | 40 +++++-------------- .../constant/const-value-display.rs | 4 +- .../constant/generic-const-items.rs | 2 +- .../constant/show-const-contents.rs | 16 ++++---- .../inline_cross/generic-const-items.rs | 2 +- 6 files changed, 32 insertions(+), 55 deletions(-) diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index e687378a501ac..bd914186ad8b0 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -442,19 +442,16 @@ fn print_const_with_custom_print_scalar<'tcx>( } pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool { - if let hir::Node::Expr(expr) = tcx.hir_node(hir_id) { - if let hir::ExprKind::Lit(_) = &expr.kind { - return true; - } - - if let hir::ExprKind::Unary(hir::UnOp::Neg, expr) = &expr.kind - && let hir::ExprKind::Lit(_) = &expr.kind - { - return true; - } - } - - false + use ExprKind::{Lit, Path, Unary}; + use hir::{Expr, ExprKind, Node, UnOp}; + + matches!( + tcx.hir_node(hir_id), + Node::Expr(Expr { + kind: Lit(_) | Path(_) | Unary(UnOp::Neg, Expr { kind: Lit(_) | Path(_), .. }), + .. + }) + ) } /// Given a type Path, resolve it to a Type using the TyCtxt diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 84e93a479b5b5..e5e89cbbd4627 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1920,9 +1920,19 @@ fn item_constant( let tcx = cx.tcx(); render_attributes_in_code(w, it, "", cx)?; + let val = fmt::from_fn(|f| { + let is_literal = c.is_literal(tcx); + let expr = c.expr(tcx); + if is_literal { + write!(f, " = {expr}", expr = Escape(&expr)) + } else { + f.write_str(" = _") + } + }); + write!( w, - "{vis}const {name}{generics}: {typ}{where_clause}", + "{vis}const {name}{generics}: {typ}{val}{where_clause};", vis = visibility_print_with_space(it, cx), name = it.name.unwrap(), generics = print_generics(generics, cx), @@ -1931,34 +1941,6 @@ fn item_constant( print_where_clause(generics, cx, 0, Ending::NoNewline).maybe_display(), )?; - // FIXME: The code below now prints - // ` = _; // 100i32` - // if the expression is - // `50 + 50` - // which looks just wrong. - // Should we print - // ` = 100i32;` - // instead? - - let value = c.value(tcx); - let is_literal = c.is_literal(tcx); - let expr = c.expr(tcx); - if value.is_some() || is_literal { - write!(w, " = {expr};", expr = Escape(&expr))?; - } else { - w.write_str(";")?; - } - - if !is_literal && let Some(value) = &value { - let value_lowercase = value.to_lowercase(); - let expr_lowercase = expr.to_lowercase(); - - if value_lowercase != expr_lowercase - && value_lowercase.trim_end_matches("i32") != expr_lowercase - { - write!(w, " // {value}", value = Escape(value))?; - } - } Ok::<(), fmt::Error>(()) })?; diff --git a/tests/rustdoc-html/constant/const-value-display.rs b/tests/rustdoc-html/constant/const-value-display.rs index 658978a3490b1..8ae41f06da1a7 100644 --- a/tests/rustdoc-html/constant/const-value-display.rs +++ b/tests/rustdoc-html/constant/const-value-display.rs @@ -1,9 +1,9 @@ #![crate_name = "foo"] //@ has 'foo/constant.HOUR_IN_SECONDS.html' -//@ has - '//*[@class="rust item-decl"]//code' 'pub const HOUR_IN_SECONDS: u64 = _; // 3_600u64' +//@ has - '//*[@class="rust item-decl"]//code' 'pub const HOUR_IN_SECONDS: u64 = _;' pub const HOUR_IN_SECONDS: u64 = 60 * 60; //@ has 'foo/constant.NEGATIVE.html' -//@ has - '//*[@class="rust item-decl"]//code' 'pub const NEGATIVE: i64 = _; // -3_600i64' +//@ has - '//*[@class="rust item-decl"]//code' 'pub const NEGATIVE: i64 = _;' pub const NEGATIVE: i64 = -60 * 60; diff --git a/tests/rustdoc-html/constant/generic-const-items.rs b/tests/rustdoc-html/constant/generic-const-items.rs index 31c300f2ff1e1..b9b0d4e5f4bfe 100644 --- a/tests/rustdoc-html/constant/generic-const-items.rs +++ b/tests/rustdoc-html/constant/generic-const-items.rs @@ -3,7 +3,7 @@ //@ has 'generic_const_items/constant.K.html' //@ has - '//*[@class="rust item-decl"]//code' \ -// "pub const K<'a, T: 'a + Copy, const N: usize>: Option<[T; N]> \ +// "pub const K<'a, T: 'a + Copy, const N: usize>: Option<[T; N]> = None \ // where \ // String: From;" pub const K<'a, T: 'a + Copy, const N: usize>: Option<[T; N]> = None diff --git a/tests/rustdoc-html/constant/show-const-contents.rs b/tests/rustdoc-html/constant/show-const-contents.rs index 6d2701693ceff..664808174b9b4 100644 --- a/tests/rustdoc-html/constant/show-const-contents.rs +++ b/tests/rustdoc-html/constant/show-const-contents.rs @@ -21,14 +21,14 @@ pub const CONST_NEG_I32: i32 = -42; //@ !hasraw show_const_contents/constant.CONST_EQ_TO_VALUE_I32.html '// 42i32' pub const CONST_EQ_TO_VALUE_I32: i32 = 42i32; -//@ hasraw show_const_contents/constant.CONST_CALC_I32.html '= _; // 43i32' +//@ hasraw show_const_contents/constant.CONST_CALC_I32.html '= _;' pub const CONST_CALC_I32: i32 = 42 + 1; //@ !hasraw show_const_contents/constant.CONST_REF_I32.html '= &42;' //@ !hasraw show_const_contents/constant.CONST_REF_I32.html '; //' pub const CONST_REF_I32: &'static i32 = &42; -//@ hasraw show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX; // 2_147_483_647i32' +//@ hasraw show_const_contents/constant.CONST_I32_MAX.html '= i32::MAX;' pub const CONST_I32_MAX: i32 = i32::MAX; //@ !hasraw show_const_contents/constant.UNIT.html '= ();' @@ -47,21 +47,19 @@ pub struct MyTypeWithStr(&'static str); //@ !hasraw show_const_contents/constant.MY_TYPE_WITH_STR.html '; //' pub const MY_TYPE_WITH_STR: MyTypeWithStr = MyTypeWithStr("show this"); -//@ hasraw show_const_contents/constant.PI.html '= 3.14159265358979323846264338327950288_f32;' -//@ hasraw show_const_contents/constant.PI.html '; // 3.14159274f32' +//@ hasraw show_const_contents/constant.PI.html '= _;' pub use std::f32::consts::PI; - -//@ hasraw show_const_contents/constant.MAX.html '= i32::MAX; // 2_147_483_647i32' +//@ hasraw show_const_contents/constant.MAX.html '= i32::MAX;' #[allow(deprecated, deprecated_in_future)] pub use std::i32::MAX; macro_rules! int_module { - ($T:ident) => ( + ($T:ident) => { pub const MIN: $T = $T::MIN; - ) + }; } -//@ hasraw show_const_contents/constant.MIN.html '= i16::MIN; // -32_768i16' +//@ hasraw show_const_contents/constant.MIN.html '= i16::MIN;' int_module!(i16); //@ has show_const_contents/constant.ESCAPE.html //pre '= r#""#;' diff --git a/tests/rustdoc-html/inline_cross/generic-const-items.rs b/tests/rustdoc-html/inline_cross/generic-const-items.rs index 70018b6ddb556..8145ded284c97 100644 --- a/tests/rustdoc-html/inline_cross/generic-const-items.rs +++ b/tests/rustdoc-html/inline_cross/generic-const-items.rs @@ -5,7 +5,7 @@ //@ has 'user/constant.K.html' //@ has - '//*[@class="rust item-decl"]//code' \ -// "pub const K<'a, T: 'a + Copy, const N: usize>: Option<[T; N]> \ +// "pub const K<'a, T: 'a + Copy, const N: usize>: Option<[T; N]> = _ \ // where \ // String: From;" pub use generic_const_items::K; From d6018cf4a4da98458d617c87ee5d491b71d128d5 Mon Sep 17 00:00:00 2001 From: Yotam Ofek Date: Mon, 5 Jan 2026 14:46:50 +0200 Subject: [PATCH 3/3] fix `rustdoc-ui` tests --- tests/rustdoc-ui/const-evalutation-ice.rs | 2 +- tests/rustdoc-ui/const-evalutation-ice.stderr | 9 --------- tests/rustdoc-ui/issues/issue-79494.rs | 2 +- tests/rustdoc-ui/issues/issue-79494.stderr | 9 --------- tests/rustdoc-ui/track-diagnostics.rs | 8 +------- tests/rustdoc-ui/track-diagnostics.stderr | 11 ----------- 6 files changed, 3 insertions(+), 38 deletions(-) delete mode 100644 tests/rustdoc-ui/const-evalutation-ice.stderr delete mode 100644 tests/rustdoc-ui/issues/issue-79494.stderr delete mode 100644 tests/rustdoc-ui/track-diagnostics.stderr diff --git a/tests/rustdoc-ui/const-evalutation-ice.rs b/tests/rustdoc-ui/const-evalutation-ice.rs index 72bcbeb4c5160..09166acbe3a22 100644 --- a/tests/rustdoc-ui/const-evalutation-ice.rs +++ b/tests/rustdoc-ui/const-evalutation-ice.rs @@ -1,3 +1,4 @@ +//@ check-pass // Just check we don't get an ICE for `N`. use std::cell::Cell; @@ -8,4 +9,3 @@ pub struct S { } pub const N: usize = 0 - (mem::size_of::() != 400) as usize; -//~^ ERROR overflow diff --git a/tests/rustdoc-ui/const-evalutation-ice.stderr b/tests/rustdoc-ui/const-evalutation-ice.stderr deleted file mode 100644 index 51958319f5fbd..0000000000000 --- a/tests/rustdoc-ui/const-evalutation-ice.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0080]: attempt to compute `0_usize - 1_usize`, which would overflow - --> $DIR/const-evalutation-ice.rs:10:22 - | -LL | pub const N: usize = 0 - (mem::size_of::() != 400) as usize; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `N` failed here - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/rustdoc-ui/issues/issue-79494.rs b/tests/rustdoc-ui/issues/issue-79494.rs index 737c00a0269bb..4e72457716844 100644 --- a/tests/rustdoc-ui/issues/issue-79494.rs +++ b/tests/rustdoc-ui/issues/issue-79494.rs @@ -1,6 +1,6 @@ +//@ check-pass //@ only-64bit #![feature(const_transmute)] pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; -//~^ ERROR transmuting from 8-byte type to 16-byte type diff --git a/tests/rustdoc-ui/issues/issue-79494.stderr b/tests/rustdoc-ui/issues/issue-79494.stderr deleted file mode 100644 index fa797bfd50a69..0000000000000 --- a/tests/rustdoc-ui/issues/issue-79494.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0080]: transmuting from 8-byte type to 16-byte type: `usize` -> `&[u8]` - --> $DIR/issue-79494.rs:5:33 - | -LL | pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ evaluation of `ZST` failed here - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0080`. diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs index f8e710659a5c8..13f5267f23912 100644 --- a/tests/rustdoc-ui/track-diagnostics.rs +++ b/tests/rustdoc-ui/track-diagnostics.rs @@ -1,13 +1,7 @@ +//@ check-pass //@ compile-flags: -Z track-diagnostics -// Normalize the emitted location so this doesn't need -// updating everytime someone adds or removes a line. -//@ normalize-stderr: ".rs:\d+:\d+" -> ".rs:LL:CC" - struct A; struct B; pub const S: A = B; -//~^ ERROR mismatched types -//~| NOTE created at -//~| NOTE expected `A`, found `B` diff --git a/tests/rustdoc-ui/track-diagnostics.stderr b/tests/rustdoc-ui/track-diagnostics.stderr deleted file mode 100644 index a25fd2862aaf0..0000000000000 --- a/tests/rustdoc-ui/track-diagnostics.stderr +++ /dev/null @@ -1,11 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/track-diagnostics.rs:LL:CC - | -LL | pub const S: A = B; - | ^ expected `A`, found `B` - | - = note: -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`.