You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #37660 separates impl items from impls in the HIR for improved interaction with incremental compilation. It probably makes sense to separate foreign items in this way too -- not so much for improved incremental compilation precision, as because it makes the layout more analogous.
Marking this as E-mentor. I'll give a short write-up here; happy to provide a more detailed one too upon request!
The work that needs to be done is basically to model foreign items on impl items -- we would get a hir::ForeignItemRef like hir::ImplItemRef, a separate map in the Krate to store them, and modify the lowering routines analogously. Finally, there are a few places (marked with FIXMEs attached to this issue number) where we could convert to using a ItemLikeVisitor if foreign items were considered "item like".
Something I've wanted to do for a while is just remove the pointless "foreign mod" nonsense in HIR.
We just need to stick the attributes from the extern {...} somewhere at the crate level or something.
So an ImplItem is any item that appears within the block of an impl? And a ForeignItem is any item that appears inside an extern block? What about extern "C" fn foo() { }?
What needs to be done in order to get rid of the "pointless foreign mod nonsense"? Would you like ForeignMod to be removed? What should happen with the data then?
What needs to be done in order to get rid of the "pointless foreign mod nonsense"?
Suppose we have a foreign module like this:
#[link(name = "qwerty")]
extern "C" {
fn f();
}
, then foreign items (f) need to be transplanted from the foreign module into the normal non-foreign parent module, ABI ("C") moved from the foreign module to foreign items, and attributes like #[link(name = "qwerty")] moved... somewhere.
One question is whether we might want to have a bunch of imports that share some common information - AFAIK all the attributes on an extern "ABI" {...} don't affect the imports inside but rather the crate.
These associations are extracted pretty early on and stored in CStore (indexed by DefId), so I don't think there's any dependency on hir::ItemForeignMod for this feature.
@retep998@vadimcn I'm not sure it's feasible to lift "foreign items" to the surrounding scope, even if just because of the lint scoping issue, i.e. #[allow(x)] extern {...} applies to everything inside.
If we had a way of cheaply duplicating such attributes... maybe, but still. It's annoying because they're almost regular items, and having them separate from all the other items is complexity I'd like to get rid of.
@eddyb to be perfectly honest, I've not been following the discussion that closely. I just read over it. I agree with your intuition that it would be nice to lift them, but there seem to be some practical hurdles in the way:
First, that there is still a concept of a "foreign item" that these items are embedded within; I believe that is relevant to linking both on Windows (dllimport) and Mac OS/X (frameworks), but I'm no expert
Second, that we would want to respect lint scoping.
It seems to me that my original plan -- to keep the ForeignMod in the HIR but make foreign items into "item-like" things -- would have much of the same benefit. If you use visit_all_item_likes_in_hir, then you can ignore the existence of ForeignMod, and if you care, it's still there.
Ultimately it seems like ForeignMod is a concept we will have to represent, just like impls and traits, whether we do it by having an item in the HIR or by having something "on the side".
Can we move them to Item and effectively keep ForeignMod around as a weird sort of module?
And/or point to the NodeId of the ForeignMod from each item lifted from it, without actual parenting.
Can we [...] point to the NodeId of the ForeignMod from each item lifted from it, without actual parenting.
I considered this, but it seems not obviously good. e.g., it means that the HIR will not reflect the DefPath hierarchy, and lints will have to work around it.
Can we move them to Item and effectively keep ForeignMod around as a weird sort of module?
This is sort of interesting-- since name resolution is already done, I guess we don't care too much. I'm still having trouble seeing the value here, I have to admit, over just making them item-like. Perhaps there is lots of code that gets simplified? I guess that compared to impl-item and trait-item, foreign-item seems like small potatoes.
Activity
nikomatsakis commentedon Nov 11, 2016
Marking this as E-mentor. I'll give a short write-up here; happy to provide a more detailed one too upon request!
The work that needs to be done is basically to model foreign items on impl items -- we would get a
hir::ForeignItemReflikehir::ImplItemRef, a separate map in theKrateto store them, and modify the lowering routines analogously. Finally, there are a few places (marked with FIXMEs attached to this issue number) where we could convert to using aItemLikeVisitorif foreign items were considered "item like".eddyb commentedon Nov 11, 2016
Something I've wanted to do for a while is just remove the pointless "foreign mod" nonsense in HIR.
We just need to stick the attributes from the
extern {...}somewhere at the crate level or something.aochagavia commentedon Dec 12, 2016
For someone who has never worked on anything hir-related... Could you give examples of Rust code that compiles down to:
ImplItem?ForeignItem?petrochenkov commentedon Dec 12, 2016
@aochagavia
aochagavia commentedon Dec 12, 2016
So an
ImplItemis any item that appears within the block of animpl? And aForeignItemis any item that appears inside anexternblock? What aboutextern "C" fn foo() { }?petrochenkov commentedon Dec 12, 2016
Yes.
It's just a
FnItemusing non-default ABI.aochagavia commentedon Dec 12, 2016
Thanks!
Now some more questions, about what @eddyb said:
ForeignMod? Is my interpretation below correct?ForeignModto be removed? What should happen with the data then?petrochenkov commentedon Dec 12, 2016
Yes.
Suppose we have a foreign module like this:
, then foreign items (
f) need to be transplanted from the foreign module into the normal non-foreign parent module, ABI ("C") moved from the foreign module to foreign items, and attributes like#[link(name = "qwerty")]moved... somewhere.aochagavia commentedon Dec 12, 2016
Does that mean that
ForeignModwouldn't be needed anymore? Or are there other types ofForeignMod?petrochenkov commentedon Dec 12, 2016
Yeah, the whole point of this exercise is to get rid of
ForeignMod(in HIR).eddyb commentedon Dec 12, 2016
One question is whether we might want to have a bunch of imports that share some common information - AFAIK all the attributes on an
extern "ABI" {...}don't affect the imports inside but rather the crate.cc @retep998
3 remaining items
vadimcn commentedon Dec 13, 2016
These associations are extracted pretty early on and stored in
CStore(indexed by DefId), so I don't think there's any dependency onhir::ItemForeignModfor this feature.eddyb commentedon Dec 13, 2016
@retep998 @vadimcn I'm not sure it's feasible to lift "foreign items" to the surrounding scope, even if just because of the lint scoping issue, i.e.
#[allow(x)] extern {...}applies to everything inside.If we had a way of cheaply duplicating such attributes... maybe, but still. It's annoying because they're almost regular items, and having them separate from all the other items is complexity I'd like to get rid of.
cramertj commentedon Jan 25, 2017
@aochagavia Are you working on this? If not, I'd like to try it.
eddyb commentedon Jan 25, 2017
@nikomatsakis Did we even come to an consensus on this? It'd be nice not to have "foreign items".
aochagavia commentedon Jan 26, 2017
@cramertj Go ahead! I never figured out what exactly needed to happen, so I didn't even start working on it.
cramertj commentedon Jan 26, 2017
@aochagavia If I understand @eddyb's comment correctly, it doesn't sound like there's been a decision as to what should be done.
nikomatsakis commentedon Jan 27, 2017
@eddyb to be perfectly honest, I've not been following the discussion that closely. I just read over it. I agree with your intuition that it would be nice to lift them, but there seem to be some practical hurdles in the way:
It seems to me that my original plan -- to keep the
ForeignModin the HIR but make foreign items into "item-like" things -- would have much of the same benefit. If you usevisit_all_item_likes_in_hir, then you can ignore the existence ofForeignMod, and if you care, it's still there.Ultimately it seems like
ForeignModis a concept we will have to represent, just like impls and traits, whether we do it by having an item in the HIR or by having something "on the side".eddyb commentedon Jan 27, 2017
Can we move them to
Itemand effectively keepForeignModaround as a weird sort of module?And/or point to the
NodeIdof theForeignModfrom each item lifted from it, without actual parenting.nikomatsakis commentedon Jan 27, 2017
@eddyb
Reordering slightly:
I considered this, but it seems not obviously good. e.g., it means that the HIR will not reflect the
DefPathhierarchy, and lints will have to work around it.This is sort of interesting-- since name resolution is already done, I guess we don't care too much. I'm still having trouble seeing the value here, I have to admit, over just making them item-like. Perhaps there is lots of code that gets simplified? I guess that compared to impl-item and trait-item, foreign-item seems like small potatoes.
nikomatsakis commentedon Jan 27, 2017
(But maybe we can think of an approach that works for all of those things?)
tamird commentedon Apr 8, 2018
Seems like this is not fully baked enough to be E-mentor.
cjgillot commentedon Jan 23, 2021
Solved by #79318.