summaryrefslogtreecommitdiffstats
path: root/tests/rustdoc/hide-complex-unevaluated-const-arguments.rs
blob: 6006354eba4e5154c455771b4b4b79291890b5fc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Test that certain unevaluated constant expression arguments that are
// deemed too verbose or complex and that may leak private or
// `doc(hidden)` struct fields are not displayed in the documentation.
//
// Read the documentation of `rustdoc::clean::utils::print_const_expr`
// for further details.
#![feature(const_trait_impl, generic_const_exprs)]
#![allow(incomplete_features)]

// @has hide_complex_unevaluated_const_arguments/trait.Stage.html
pub trait Stage {
    // A helper constant that prevents const expressions containing it
    // from getting fully evaluated since it doesn't have a body and
    // thus is non-reducible. This allows us to specifically test the
    // pretty-printing of *unevaluated* consts.
    const ABSTRACT: usize;

    // Currently considered "overly complex" by the `generic_const_exprs`
    // feature. If / once this expression kind gets supported, this
    // unevaluated const expression could leak the private struct field.
    //
    // FIXME: Once the line below compiles, make this a test that
    //        ensures that the private field is not printed.
    //
    //const ARRAY0: [u8; Struct { private: () } + Self::ABSTRACT];

    // This assoc. const could leak the private assoc. function `Struct::new`.
    // Ensure that this does not happen.
    //
    // @has - '//*[@id="associatedconstant.ARRAY1"]' \
    //        'const ARRAY1: [u8; { _ }]'
    const ARRAY1: [u8; Struct::new(/* ... */).do_something(Self::ABSTRACT * 1_000)];

    // @has - '//*[@id="associatedconstant.VERBOSE"]' \
    //        'const VERBOSE: [u16; { _ }]'
    const VERBOSE: [u16; compute("thing", 9 + 9) * Self::ABSTRACT];

    // Check that we do not leak the private struct field contained within
    // the path. The output could definitely be improved upon
    // (e.g. printing sth. akin to `<Self as Helper<{ _ }>>::OUT`) but
    // right now “safe is safe”.
    //
    // @has - '//*[@id="associatedconstant.PATH"]' \
    //        'const PATH: usize = _'
    const PATH: usize = <Self as Helper<{ Struct { private: () } }>>::OUT;
}

const fn compute(input: &str, extra: usize) -> usize {
    input.len() + extra
}

pub trait Helper<const S: Struct> {
    const OUT: usize;
}

impl<const S: Struct, St: Stage + ?Sized> Helper<S> for St {
    const OUT: usize = St::ABSTRACT;
}

// Currently in rustdoc, const arguments are not evaluated in this position
// and therefore they fall under the realm of `print_const_expr`.
// If rustdoc gets patched to evaluate const arguments, it is fine to replace
// this test as long as one can ensure that private fields are not leaked!
//
// @has hide_complex_unevaluated_const_arguments/trait.Sub.html \
//      '//pre[@class="rust item-decl"]' \
//      'pub trait Sub: Sup<{ _ }, { _ }> { }'
pub trait Sub: Sup<{ 90 * 20 * 4 }, { Struct { private: () } }> {}

pub trait Sup<const N: usize, const S: Struct> {}

pub struct Struct { private: () }

impl Struct {
    const fn new() -> Self { Self { private: () } }
    const fn do_something(self, x: usize) -> usize {
        x
    }
}
/* FIXME(const-trait): readd this
impl const std::ops::Add<usize> for Struct {
    type Output = usize;

    fn add(self, _: usize) -> usize { 0 }
}
*/