Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upSeparate function bodies from their signatures in HIR #37918
Conversation
rust-highfive
assigned
nikomatsakis
Nov 21, 2016
This comment has been minimized.
This comment has been minimized.
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nikomatsakis (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
nikomatsakis
requested changes
Nov 21, 2016
|
OK, this is looking really good! I had a few comments as to possible other ways that we could do things. I'm not sure which, if any, we should do before landing. I might have to experiment locally to form a real opinion in any case. Curious to get your opinion. These are the major themes I remember:
I have some thoughts on the last one, but I think it'd be easier for me to just experiment locally and send you a diff if what I am saying makes sense. =) |
| impl<'v> Visitor<'v> for IdRangeComputingVisitor { | ||
| impl<'a, 'ast> Visitor<'ast> for IdRangeComputingVisitor<'a, 'ast> { | ||
| fn nested_visit_map(&mut self) -> Option<(&Map<'ast>, NestedVisitMode)> { | ||
| Some((&self.map, NestedVisitMode::OnlyBodies)) |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Nov 21, 2016
Contributor
Ah, of course... in our latest comments on the issue, I had forgotten the central problem where you want to visit fn bodies as the default, but of course we don't have the map by default... my inclination is to make the nested_body_map be a separate method, and make it have no default implementation, so that we always specify it for every visitor. I feel like it is potentially much more surprising to skip over bodies.
This comment has been minimized.
This comment has been minimized.
| self.handle(|i: ItemFnParts<'a>| i.body, | ||
| |_, _, _: &'a ast::MethodSig, _, body: ast::ExprId, _, _| body, | ||
| |c: ClosureParts<'a>| c.body) | ||
| } | ||
|
|
||
| pub fn decl(self) -> &'a FnDecl { | ||
| if let map::NodeInlinedItem(&InlinedItem { kind: InlinedItemKind::Fn(ref decl), .. }) = self.node { | ||
| return &decl; | ||
| } | ||
| self.handle(|i: ItemFnParts<'a>| &*i.decl, |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Nov 21, 2016
Contributor
Seems like the most natural way to extend this code would be extend handle to cover this case, probably by adding a fourth closure callback (inlined-item).
| fn_like.body(), | ||
| fn_like.span(), | ||
| fn_like.id()); | ||
| let qualif = match self.tcx.const_qualif_map.borrow_mut().entry(fn_like.body().node_id()) { |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Nov 21, 2016
Contributor
What is happening here? Is this populated for inlined items or something? At minimum, some comments seem good.
This comment has been minimized.
This comment has been minimized.
flodiebold
Nov 21, 2016
Author
Contributor
Ah, yeah. Because the FnLike interface is only half implemented for inlined items, the fn_like call would fail for them, but the const_qualif_map is already populated for them, so I added the check beforehand. I'll need to clean that up somehow...
| Item(DefId /* def-id in source crate */, P<hir::Item>), | ||
| TraitItem(DefId /* impl id */, P<hir::TraitItem>), | ||
| ImplItem(DefId /* impl id */, P<hir::ImplItem>) | ||
| pub struct InlinedItem { |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Nov 21, 2016
Contributor
It's hard for me to assess if this is the best way -- vs say trying to encode the fn bodies separately. Apart from some nits (which I tried to cite), it does seem a bit cleaner than what was here before, though. Perhaps @eddyb has an opinion. But overall I think I like it?
This comment has been minimized.
This comment has been minimized.
eddyb
Nov 21, 2016
Member
Seems okay - shouldn't need the type of a constant though, in fact, you should be able to only record a Vec<DefId> for the arguments of a const fn, which doesn't even need to be in a separate enum anymore, just replace the kind field with const_fn_args: Vec<DefId> and that should be that.
This comment has been minimized.
This comment has been minimized.
flodiebold
Nov 24, 2016
Author
Contributor
That would make implementing FnLike even harder, though, I think.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
flodiebold
Nov 24, 2016
Author
Contributor
lookup_const_fn_by_id returns an FnLikeNode currently. But I guess it could return something else, e.g. a new enum?
This comment has been minimized.
This comment has been minimized.
eddyb
Nov 24, 2016
Member
Yeah, that would make more sense, FnLikeNode is more about pretty-printing.
| @@ -42,6 +42,9 @@ pub enum DepNode<D: Clone + Debug> { | |||
| // Represents the HIR node with the given node-id | |||
| Hir(D), | |||
|
|
|||
| // Represents the body of a function or method | |||
| HirBody(D), | |||
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Nov 21, 2016
Contributor
This comment should specify that D is the def-id of the fn/method, as opposed to the id of the body itself.
As an alternative, we could get rid of this variant and give expression bodies their own def-id. Not yet sure which approach I prefer, have to read more.
| @@ -31,7 +31,7 @@ mod x { | |||
| mod y { | |||
| use x; | |||
|
|
|||
| #[rustc_dirty(label="TypeckItemBody", cfg="rpass2")] | |||
| #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] | |||
This comment has been minimized.
This comment has been minimized.
| fn col_same() { | ||
| let _ = column!(); | ||
| } | ||
|
|
||
| #[rustc_clean(label="Hir", cfg="rpass2")] | ||
| #[rustc_clean(label="HirBody", cfg="rpass2")] |
This comment has been minimized.
This comment has been minimized.
| @@ -144,6 +144,7 @@ impl<'a> InlinedItemRef<'a> { | |||
| pub fn from_trait_item(def_id: DefId, item: &'a hir::TraitItem, _map: &hir_map::Map) -> InlinedItemRef<'a> { | |||
| let (body, kind) = match item.node { | |||
| hir::ConstTraitItem(ref ty, Some(ref body)) => (&**body, InlinedItemKindRef::Const(ty)), | |||
| hir::ConstTraitItem(_, None) => bug!("InlinedItemRef::from_trait_item called for const without body"), | |||
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
flodiebold
Nov 21, 2016
Author
Contributor
The code which calls from_trait_item takes care to only call it when there's a body, but I accidentally changed that once, and it wasn't immediately clear to me what I'd done wrong, so I just added this special message in case it happens again.
| fn visit_item(&mut self, item: &hir::Item) { | ||
| impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> { | ||
| fn nested_visit_map(&mut self) -> Option<(&hir::map::Map<'tcx>, NestedVisitMode)> { | ||
| Some((&self.ccx.tcx.map, NestedVisitMode::OnlyBodies)) |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Nov 21, 2016
Contributor
Hmm, this is suboptimal from the POV of the dep-graph tasks. We don't want the task which writes to the signature of a fn also reading from the fn body. Not sure what's the best way to tweak that just now; it's certainly possible.
| #[rustc_clean(label="TypeckItemBody", cfg="rpass2")] | ||
| pub fn y() { | ||
| x::x(); | ||
| // FIXME: This should be clean |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Nov 21, 2016
Contributor
I think the problem is the issue of collect reading from the fn body that I pointed out earlier.
This comment has been minimized.
This comment has been minimized.
|
Giving def-ids to bodies didn't really occur to me (I was thinking only definitions can have def-ids). That would probably make a few things cleaner, but I don't really have the perspective to know what else it may complicate. Also, how would the testing attributes work? Can you give attributes to expressions? |
This comment has been minimized.
This comment has been minimized.
|
@flodiebold so I pushed two commits into your branch -- take a look. The first one fixes the |
This comment has been minimized.
This comment has been minimized.
You can give attributes to statements, not expressions. So that is a possible complication; I guess we could look for an attribute on the first statement of a block or something. |
This comment has been minimized.
This comment has been minimized.
|
@flodiebold all in all, the main thing I'd prefer to settle now is the visitor trait -- i.e., whether to have another method. The |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@nikomatsakis It does seem to me like having two methods and having no default for I'll fix the remaining tests; I think they may have come in during my last rebase, after which I forgot to check them again :) |
This comment has been minimized.
This comment has been minimized.
Great =) If that change is made and tests are working, I think this PR is ready to go. We can revisit the |
This comment has been minimized.
This comment has been minimized.
|
@eddyb I refactored the inlined item handling again. I didn't get rid of the @nikomatsakis Ok, I think I've addressed everything. |
This comment has been minimized.
This comment has been minimized.
|
@michaelwoerister By the way, the |
This comment has been minimized.
This comment has been minimized.
|
@flodiebold Good catch. Yes, maybe we can let the rest runner do some checks to prevent this. |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@flodiebold The commit "Merge master into separate-bodies" is worrying me - did you |
This comment has been minimized.
This comment has been minimized.
|
@eddyb I did merge because I wasn't sure whether a merge or a rebase is the preferred way to resolve conflicts. But I've actually just done a rebase onto the current master, so I could push that too. Apart from that, I think the PR is ready and just needs to be looked at again. |
This comment has been minimized.
This comment has been minimized.
|
@flodiebold Rebase + force push is the way, only @bors does merges (into the |
This comment has been minimized.
This comment has been minimized.
|
Ok, that's what I preferred anyway. Rebased version coming up. |
flodiebold
force-pushed the
flodiebold:separate-bodies
branch
from
cd9e807
to
5162288
Nov 28, 2016
This comment has been minimized.
This comment has been minimized.
|
@flodiebold I was experimenting with an alternative version of the visitor refactoring. I've just rebased it atop your rebase, once it builds I'll push it to your branch and you can tell me what you think. It's actually sort of closer to your original approach. |
This comment has been minimized.
This comment has been minimized.
|
done. |
This comment has been minimized.
This comment has been minimized.
|
Pushed one more commit updating the comments a bit. |
nikomatsakis
approved these changes
Nov 28, 2016
This comment has been minimized.
This comment has been minimized.
|
@flodiebold (if you are happy with my latest commit, then r=me on the PR) |
This comment has been minimized.
This comment has been minimized.
|
Ah, that does seem nicer. Makes it easier to search for visitors which currently don't return a map, too. |
This comment has been minimized.
This comment has been minimized.
|
@bors r+ |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
|
@bors r- failed Travis ( |
This comment has been minimized.
This comment has been minimized.
|
|
nikomatsakis
and others
added some commits
Nov 21, 2016
flodiebold
force-pushed the
flodiebold:separate-bodies
branch
from
f620072
to
bc9bae9
Nov 29, 2016
flodiebold
force-pushed the
flodiebold:separate-bodies
branch
from
bc9bae9
to
593b273
Nov 29, 2016
This comment has been minimized.
This comment has been minimized.
|
@eddyb @nikomatsakis Fixed and rebased :) |
This comment has been minimized.
This comment has been minimized.
|
@bors r=nikomatsakis |
This comment has been minimized.
This comment has been minimized.
|
|
This comment has been minimized.
This comment has been minimized.
bors
added a commit
that referenced
this pull request
Nov 29, 2016
This comment has been minimized.
This comment has been minimized.
|
@flodiebold great, thanks! |
flodiebold commentedNov 21, 2016
Also give them their own dep map node.
I'm still unhappy with the handling of inlined items (1452edc), but maybe you have a suggestion how to improve it.
Fixes #35078.
r? @nikomatsakis