Skip to content

Separate foreign items in HIR #37713

Closed
Closed

Description

@nikomatsakis

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.

Activity

  1. added
    A-incr-compArea: Incremental compilation
    E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
    on Nov 11, 2016
  2. nikomatsakis commented on Nov 11, 2016

    @nikomatsakis
    ContributorAuthor

    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".

  3. added
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    C-cleanupCategory: PRs that clean code up or issues documenting cleanup.
    on Nov 11, 2016
  4. eddyb commented on Nov 11, 2016

    @eddyb
    Contributor

    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.

  5. aochagavia commented on Dec 12, 2016

    @aochagavia
    Contributor

    For someone who has never worked on anything hir-related... Could you give examples of Rust code that compiles down to:

    • An ImplItem?
    • A ForeignItem?
  6. petrochenkov commented on Dec 12, 2016

    @petrochenkov
    Contributor

    @aochagavia

    impl Trait for Type {
        fn f() {} // <-- ImplItem
    }
    impl Type {
        fn g() {} // <-- ImplItem
    }
    extern "C" {
        fn printf(); // <-- ForeignItem
    }
    
  7. aochagavia commented on Dec 12, 2016

    @aochagavia
    Contributor

    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() { }?

  8. petrochenkov commented on Dec 12, 2016

    @petrochenkov
    Contributor

    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?

    Yes.

    What about extern "C" fn foo() { }?

    It's just a Fn Item using non-default ABI.

  9. aochagavia commented on Dec 12, 2016

    @aochagavia
    Contributor

    Thanks!

    Now some more questions, about what @eddyb said:

    1. Could you give examples of Rust code that are represented as a ForeignMod? Is my interpretation below correct?
    extern "C" { // <-- ForeignMod?
        fn printf(); // <-- ForeignItem
    }
    
    1. 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?
  10. petrochenkov commented on Dec 12, 2016

    @petrochenkov
    Contributor

    Is my interpretation below correct?

    Yes.

    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.

  11. aochagavia commented on Dec 12, 2016

    @aochagavia
    Contributor

    Does that mean that ForeignMod wouldn't be needed anymore? Or are there other types of ForeignMod?

  12. petrochenkov commented on Dec 12, 2016

    @petrochenkov
    Contributor

    Yeah, the whole point of this exercise is to get rid of ForeignMod (in HIR).

  13. eddyb commented on Dec 12, 2016

    @eddyb
    Contributor

    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

  14. 3 remaining items

  15. vadimcn commented on Dec 13, 2016

    @vadimcn
    Contributor

    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.

  16. eddyb commented on Dec 13, 2016

    @eddyb
    Contributor

    @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.

  17. cramertj commented on Jan 25, 2017

    @cramertj
    Member

    @aochagavia Are you working on this? If not, I'd like to try it.

  18. eddyb commented on Jan 25, 2017

    @eddyb
    Contributor

    @nikomatsakis Did we even come to an consensus on this? It'd be nice not to have "foreign items".

  19. aochagavia commented on Jan 26, 2017

    @aochagavia
    Contributor

    @cramertj Go ahead! I never figured out what exactly needed to happen, so I didn't even start working on it.

  20. cramertj commented on Jan 26, 2017

    @cramertj
    Member

    @aochagavia If I understand @eddyb's comment correctly, it doesn't sound like there's been a decision as to what should be done.

  21. nikomatsakis commented on Jan 27, 2017

    @nikomatsakis
    ContributorAuthor

    @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".

  22. eddyb commented on Jan 27, 2017

    @eddyb
    Contributor

    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.

  23. nikomatsakis commented on Jan 27, 2017

    @nikomatsakis
    ContributorAuthor

    @eddyb

    Reordering slightly:

    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.

  24. nikomatsakis commented on Jan 27, 2017

    @nikomatsakis
    ContributorAuthor

    (But maybe we can think of an approach that works for all of those things?)

  25. tamird commented on Apr 8, 2018

    @tamird
    Contributor

    Seems like this is not fully baked enough to be E-mentor.

  26. removed
    E-mentorCall for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
    on Apr 8, 2018
  27. added
    A-HIRArea: The high-level intermediate representation (HIR)
    on Apr 18, 2020
  28. cjgillot commented on Jan 23, 2021

    @cjgillot
    Contributor

    Solved by #79318.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-HIRArea: The high-level intermediate representation (HIR)A-incr-compArea: Incremental compilationC-cleanupCategory: PRs that clean code up or issues documenting cleanup.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions