- 
                Notifications
    
You must be signed in to change notification settings  - Fork 13.9k
 
[rustdoc] Add support new bang macro kinds #145458
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
[rustdoc] Add support new bang macro kinds #145458
Conversation
| 
           r? @notriddle rustbot has assigned @notriddle. Use   | 
    
| 
           Some changes occurred in HTML/CSS/JS.  | 
    
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 can't really say much about the actual logic correctness (it seems mostly fine?), but i do have a few nitpicks about naming, datatype structure and logic clarity.
It was also a bit weird reviewing this with the two alternate implementations, since as far as I can tell there's a few lines of code that are common between both impls, but actually have different semantics between them.
| 
           @rustbot author  | 
    
e173857    to
    08c5d0c      
    Compare
  
    
      
        
              This comment has been minimized.
        
        
      
    
  This comment has been minimized.
08c5d0c    to
    ac60bd4      
    Compare
  
    
      
        
              This comment has been minimized.
        
        
      
    
  This comment has been minimized.
ac60bd4    to
    8729f78      
    Compare
  
    | 
           @rustbot ready  | 
    
| 
           ☔ The latest upstream changes (presumably #138907) made this pull request unmergeable. Please resolve the merge conflicts.  | 
    
| 
           ping @lolbinarycat  | 
    
| 
           Please add a test that demonstrates how these interact with search item kind filters, and also with kind disambiguators in intra-doc links. I'm not entirely sure what the ideal behavior is in either case, but we definitely should have tests for whatever it is.  | 
    
8729f78    to
    2b98060      
    Compare
  
    | 
           This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.  | 
    
| 
           Very good idea. Should have thought about it. Added the new   | 
    
      
        
              This comment has been minimized.
        
        
      
    
  This comment has been minimized.
2b98060    to
    3cbcc53      
    Compare
  
    
      
        
              This comment has been minimized.
        
        
      
    
  This comment has been minimized.
fd9d8ae    to
    8369e78      
    Compare
  
    | 
           Fixed the search result href.  | 
    
| 
           The test needs to be updated to include the   | 
    
8369e78    to
    25eac6c      
    Compare
  
    | 
           Arf, the  Added back what I removed.  | 
    
| 
           Few more things about test coverage: 
  | 
    
25eac6c    to
    7812008      
    Compare
  
    
          
 
 With this the PR should be finally ready.  | 
    
| 
           Test still technically doesn't cover every combination of  And yeah, leaving intra-doc links for later seems reasonable, as long as its intentional.  | 
    
| _ if macro_kinds.contains(MacroKinds::BANG) => { | ||
| let kind = clean::MacroItem( | ||
| clean::Macro { | ||
| source: utils::display_macro_source(cx, name, &def), | ||
| macro_rules: def.macro_rules, | ||
| }, | ||
| macro_kinds, | ||
| ); | ||
| let mut ret = vec![]; | ||
| for kind in macro_kinds.iter().filter(|kind| *kind != MacroKinds::BANG) { | ||
| match kind { | ||
| MacroKinds::ATTR => ret.push(clean::AttrMacroItem), | ||
| MacroKinds::DERIVE => ret.push(clean::DeriveMacroItem), | ||
| _ => panic!("unsupported macro kind {kind:?}"), | ||
| } | ||
| } | ||
| (kind, Some(ret)) | ||
| } | ||
| _ => panic!("unsupported macro kind {macro_kinds:?}"), | 
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.
Now that binarycat points it out, I notice that it's not just the tests not covering every combination of MacroKinds. The code itself can't do it, even though the compiler can.
If it can't do it, then I think the design is flawed.
Instead of generating placeholders and trying to cram multiple macro kinds into a single clean::Item, maybe it should instead take the easy road and just generate duplicate pages? That way, you don't have to do any of this plumbing, and, anyway, this feature is quite niche and most crates will only want to support one mode per macro.
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.
This is unreachable unless new macro kinds are added.  a downside of the bitflags crate is it kinda ruins exhaustiveness checking for cases like this, due to having no distinction between a set of flags and a single flag. something like enumset on the other hand, doesn't have this limitation.
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's no case here that covers this:
macro_rules! macro {
    attr() () => {};
    derive() () => {};
}Such a macro has MacroKinds::DERIVE | MacroKinds::ATTR, but since it doesn't have MacroKinds::BANG, it falls through to the todo!() line.
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 implemented #148005, which should fix this problem. It also adds a bit less 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.
are you misunderstanding what bitflags iter does?
...am i misunderstanding what bitflags iter does?
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'm not sure? It says it does this:
https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/def/struct.MacroKinds.html#method.iter
Yield a set of contained flags values.
Each yielded flags value will correspond to a defined named flag. Any unknown bits will be yielded together as a final flags value.
So, assuming there aren't any unknown bits (if there are, it should fall into the default match arm and panic), and assuming that "contained" means "if I call contains() it'll return true" (I don't know what else it would mean), this should do what I want, which is to iterate through each MacroKind that is turned on for that particular macro.
In any case, I copied over most of the same test cases, and they pass.
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.
Instead of generating placeholders and trying to cram multiple macro kinds into a single clean::Item, maybe it should instead take the easy road and just generate duplicate pages? That way, you don't have to do any of this plumbing, and, anyway, this feature is quite niche and most crates will only want to support one mode per macro.
It's exactly what I wanted to avoid ^^' (hence all the extra code)
However if we add support for /// on the attr/derive branches, then this approach makes more sense.
| 
           As said in #148005, although I find the result of @notriddle's approach less good (ie, duplicated files generated for the same macro), considering how much easier the implementation is, I'd prefer for #148005 to be merged instead. Closing this one.  | 
    
…, r=notriddle [rustdoc] Simplify module rendering and HTML tags handling Extracted code from rust-lang#145458. This PR simplifies the rendering of modules, in particular the HTML tags handling. Instead of having all items in a `vec`, we make a map with their types as key, allowing to then iterate over the types, which allows us to open and close the HTML tag at every turn without the need to check if a tag was opened or not, or to check it's still the same kind of type. For a better review experience: enable "Hide whitespace", the diff will be much smaller. r? `@notriddle`
Rollup merge of #148021 - GuillaumeGomez:simplify-mod-render, r=notriddle [rustdoc] Simplify module rendering and HTML tags handling Extracted code from #145458. This PR simplifies the rendering of modules, in particular the HTML tags handling. Instead of having all items in a `vec`, we make a map with their types as key, allowing to then iterate over the types, which allows us to open and close the HTML tag at every turn without the need to check if a tag was opened or not, or to check it's still the same kind of type. For a better review experience: enable "Hide whitespace", the diff will be much smaller. r? `@notriddle`
This implements #145153 in rustdoc. This PR voluntarily doesn't touch anything related to intra-doc links, I'll send a follow-up if needed.
So now about the implementation itself: this is a weird case where a macro can be different things at once but still only gets one file generated. I saw two ways to implement this:
ItemKind::Macrodifferently and iter through itsMacroKindsvalues.ItemKindenum, which means that when we encounter them in rendering, we need to ignore them. It also makes theItemKindenum bigger (and also needs more code to be handled). Another downside is that it needs to be handled in the JSON output.I implemented 1. in the first commit and 2. in the third commit so if we don't to keep 2., I can simply remove it. I personally have no preference for one or the other since the first is "simpler" but it's easy to forget to go through the macro kinds whereas the second needs a lot more code.Now there was an interesting improvement that came with this PR in the
html::render::print_item::item_modulefunction: I simplified its implementation and split the different parts in aHashMapwhere the key is the item type. So then, we can just iterate through the keys and open/close the section at each iteration instead of keeping anOption<section>around.cc @joshtriplett