-
Notifications
You must be signed in to change notification settings - Fork 13.4k
rustdoc: Censor certain complex unevaluated const exprs #98814
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,9 @@ | ||
#![crate_name = "foo"] | ||
|
||
// @has 'foo/constant.HOUR_IN_SECONDS.html' | ||
// @has - '//*[@class="docblock item-decl"]//code' 'pub const HOUR_IN_SECONDS: u64 = 60 * 60; // 3_600u64' | ||
// @has - '//*[@class="docblock item-decl"]//code' 'pub const HOUR_IN_SECONDS: u64 = _; // 3_600u64' | ||
pub const HOUR_IN_SECONDS: u64 = 60 * 60; | ||
|
||
// @has 'foo/constant.NEGATIVE.html' | ||
// @has - '//*[@class="docblock item-decl"]//code' 'pub const NEGATIVE: i64 = -60 * 60; // -3_600i64' | ||
// @has - '//*[@class="docblock item-decl"]//code' 'pub const NEGATIVE: i64 = _; // -3_600i64' | ||
pub const NEGATIVE: i64 = -60 * 60; |
82 changes: 82 additions & 0 deletions
82
src/test/rustdoc/hide-complex-unevaluated-const-arguments.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// 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(/* ... */) + 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 \ | ||
// '//*[@class="rust trait"]' \ | ||
// '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: () } } | ||
} | ||
|
||
impl const std::ops::Add<usize> for Struct { | ||
type Output = usize; | ||
|
||
fn add(self, _: usize) -> usize { 0 } | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Regression test for issue #97933. | ||
// | ||
// Test that certain unevaluated constant expressions 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. | ||
|
||
// @has hide_complex_unevaluated_consts/trait.Container.html | ||
pub trait Container { | ||
// 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: i32; | ||
|
||
// Ensure that the private field does not get leaked: | ||
// | ||
// @has - '//*[@id="associatedconstant.STRUCT0"]' \ | ||
// 'const STRUCT0: Struct = _' | ||
const STRUCT0: Struct = Struct { private: () }; | ||
|
||
// @has - '//*[@id="associatedconstant.STRUCT1"]' \ | ||
// 'const STRUCT1: (Struct,) = _' | ||
const STRUCT1: (Struct,) = (Struct{private: /**/()},); | ||
|
||
// Although the struct field is public here, check that it is not | ||
// displayed. In a future version of rustdoc, we definitely want to | ||
// show it. However for the time being, the printing logic is a bit | ||
// conservative. | ||
// | ||
// @has - '//*[@id="associatedconstant.STRUCT2"]' \ | ||
// 'const STRUCT2: Record = _' | ||
const STRUCT2: Record = Record { public: 5 }; | ||
|
||
// Test that we do not show the incredibly verbose match expr: | ||
// | ||
// @has - '//*[@id="associatedconstant.MATCH0"]' \ | ||
// 'const MATCH0: i32 = _' | ||
const MATCH0: i32 = match 234 { | ||
0 => 1, | ||
_ => Self::ABSTRACT, | ||
}; | ||
|
||
// @has - '//*[@id="associatedconstant.MATCH1"]' \ | ||
// 'const MATCH1: bool = _' | ||
const MATCH1: bool = match Self::ABSTRACT { | ||
_ => true, | ||
}; | ||
|
||
// Check that we hide complex (arithmetic) operations. | ||
// In this case, it is a bit unfortunate since the expression | ||
// is not *that* verbose and it might be quite useful to the reader. | ||
// | ||
// However in general, the expression might be quite large and | ||
// contain match expressions and structs with private fields. | ||
// We would need to recurse over the whole expression and even more | ||
// importantly respect operator precedence when pretty-printing | ||
// the potentially partially censored expression. | ||
// For now, the implementation is quite simple and the choices | ||
// rather conservative. | ||
// | ||
// @has - '//*[@id="associatedconstant.ARITH_OPS"]' \ | ||
// 'const ARITH_OPS: i32 = _' | ||
const ARITH_OPS: i32 = Self::ABSTRACT * 2 + 1; | ||
} | ||
|
||
pub struct Struct { private: () } | ||
|
||
pub struct Record { pub public: i32 } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.