-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Add support for macro expansion in rustdoc source code pages #137229
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
base: master
Are you sure you want to change the base?
Conversation
Some changes occurred in HTML/CSS/JS. cc @GuillaumeGomez, @jsha These commits modify the If this was unintentional then you should revert the changes before this PR is merged. |
src/librustdoc/html/highlight.rs
Outdated
"{closing}\ | ||
<span class=expansion>\ | ||
<input id={id} type=checkbox>\ | ||
<label for={id}>↕</label>{reopening}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it would force to duplicate all the common code. For example in:
func(arg, macro!(blabla), arg3);
Only macro!(blabla)
will be different, so it's not interesting to duplicate all the rest. Instead, we put the original code in a span
, the expanded one in another and then we can simply switch them based on the status of the checked
property of the input. I'm also not a big fan of our current details
approach as it requires more JS to be working fully as expected but it's a debate for another time.
This comment has been minimized.
This comment has been minimized.
49a5ec0
to
9446a39
Compare
This comment has been minimized.
This comment has been minimized.
9446a39
to
f0bf946
Compare
f0bf946
to
faf64fa
Compare
This comment has been minimized.
This comment has been minimized.
This PR modifies cc @jieyouxu |
This comment has been minimized.
This comment has been minimized.
I opened the firefox bug report: https://bugzilla.mozilla.org/show_bug.cgi?id=1949948 |
☔ The latest upstream changes (presumably #137511) made this pull request unmergeable. Please resolve the merge conflicts. |
d54f0d0
to
a3e1a8b
Compare
This comment has been minimized.
This comment has been minimized.
a3e1a8b
to
8b1c7cb
Compare
8b1c7cb
to
b666b7f
Compare
PR is ready for review. |
☔ The latest upstream changes (presumably #140702) made this pull request unmergeable. Please resolve the merge conflicts. |
b666b7f
to
224ad51
Compare
Fixed merge conflict. |
224ad51
to
c9eed92
Compare
Went around firefox bug, so now it's always displayed as expected. |
5f11280
to
fc36195
Compare
Fixed merge conflict. Diff for CSS is now much smaller. :) |
☔ The latest upstream changes (presumably #144044) made this pull request unmergeable. Please resolve the merge conflicts. |
fc36195
to
cf618ac
Compare
Fixed merge conflict. |
cf618ac
to
2c20070
Compare
…ns open inside expansion spans
2c20070
to
ff6c7a3
Compare
@fmease mentioned that patterns and statements could get macro expansion as well so I added support for both cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops forgot to submit after our chat
walk_expr(self, expr); | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also visit_pat
. For things like match () { expand!() => {} }
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe also visit_stmt
. E.g., a macro expanding to let _ = …;
(this is not an expr).
Too late, already did it. :p |
@@ -271,6 +298,104 @@ fn empty_line_number(out: &mut impl Write, _: u32, extra: &'static str) { | |||
out.write_str(extra).unwrap(); | |||
} | |||
|
|||
fn get_next_expansion<'a>( | |||
expanded_codes: Option<&'a Vec<ExpandedCode>>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like this could easily just be &[ExpandedCode]
? and also this lifetime could be omitted?
I don't see any reason we would need to distinguish between an empty vec and None, as this function would return None in either case.
struct ExpandedCodeInfo { | ||
/// Callsite of the macro. | ||
span: Span, | ||
/// Expanded macro source code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Expanded macro source code. | |
/// Expanded macro source code (html escaped) |
} else if let Some(Class::Expansion) = klass { | ||
// Nothing to escape here so we get the text to write it directly. | ||
out.write_str(text.0).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} else if let Some(Class::Expansion) = klass { | |
// Nothing to escape here so we get the text to write it directly. | |
out.write_str(text.0).unwrap(); | |
} else if let Some(Class::Expansion) = klass { | |
// This has already been escaped so we get the text to write it directly. | |
out.write_str(text.0).unwrap(); |
/// Expanded span | ||
expanded_span: Span, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Expanded span | |
expanded_span: Span, | |
/// Span of macro-generated code. | |
expanded_span: Span, |
/// HIR visitor which retrieves expanded macro. | ||
/// | ||
/// Once done, the `expanded_codes` will be transformed into a vec of [`ExpandedCode`] | ||
/// which contains more information needed when running the source code highlighter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// which contains more information needed when running the source code highlighter. | |
/// which contains the information needed when running the source code highlighter. |
nit: neither ExpandedCode
nor ExpandedCodeInfo
contains strictly more info
|
||
fn compute_expanded(mut self) -> FxHashMap<BytePos, Vec<ExpandedCode>> { | ||
self.expanded_codes.sort_unstable_by(|item1, item2| item1.span.cmp(&item2.span)); | ||
let mut expanded: FxHashMap<BytePos, Vec<ExpandedCode>> = FxHashMap::default(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let mut expanded: FxHashMap<BytePos, Vec<ExpandedCode>> = FxHashMap::default(); | |
let mut expanded: FxHashMap<BytePos, Vec<ExpandedCode>> = FxHashMap::with_capacity(self.expaned_codes.len()); |
I think that having multiple macro expansions with the same byte position should be rare enough that this is a good estimation of the hashmap size?
// used by the error-index generator, so it needs to be public | ||
pub(crate) mod macro_expansion; | ||
pub mod markdown; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// used by the error-index generator, so it needs to be public | |
pub(crate) mod macro_expansion; | |
pub mod markdown; | |
pub(crate) mod macro_expansion; | |
// used by the error-index generator, so it needs to be public | |
pub mod markdown; |
run_renderer( | ||
krate, | ||
render_opts, | ||
cache, | ||
tcx, | ||
|krate, render_opts, cache, tcx| { | ||
json::JsonRenderer::init(krate, render_opts, cache, tcx) | ||
}, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
run_renderer( | |
krate, | |
render_opts, | |
cache, | |
tcx, | |
|krate, render_opts, cache, tcx| { | |
json::JsonRenderer::init(krate, render_opts, cache, tcx) | |
}, | |
) | |
run_renderer( | |
krate, | |
render_opts, | |
cache, | |
tcx, | |
json::JsonRenderer::init, | |
) |
Does this not work? only reason I can think it wouldn't is if there's some implicit reborrowing or deref coercion that needs to happen.
opt( | ||
Unstable, | ||
Flag, | ||
"", | ||
"generate-macro-expansion", | ||
"Add possibility to expand macros in the HTML source code pages", | ||
"", | ||
), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of the flags at the end of the list are deprecated or removed. This flag should be moved before the "deprecated / removed options" comment.
@@ -0,0 +1,51 @@ | |||
// Test crate used to check the `--generate-macro-expansion` option. | |||
//@ compile-flags: -Zunstable-options --generate-macro-expansion --generate-link-to-definition | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make this test a multi-file crate, so we can ensure those are handled properly.
This is what it looks like:
You can test it here. In this case, I also enabled the
--generate-link-to-definition
to show that both options work well together.Note:
There is a bug currently in firefox where the line numbers are not displayed correctly if they're inside the "macro expansion" span: https://bugzilla.mozilla.org/show_bug.cgi?id=1949948Found a workaround around this bug.r? @notriddle