-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add a HIR to the compiler #1191
Conversation
Add a high-level intermediate representation (HIR) to the compiler. This is basically a new (and additional) AST more suited for use by the compiler. This is purely an implementation detail of the compiler. It has no effect on the language. Note that adding a HIR does not preclude adding a MIR or LIR in the future.
I am not so keen on duplicating the AST, seems like a maintenance burden. Maybe if the current code is made more composable, somehow (there's a lot of it in But I do agree that moving towards something other than the AST in the compiler is a good thing. There's also the node IDs which don't really exist for libsyntax, only the compiler assigns and inspects them. Thinking more about it, it's possible the HIR could throw away most structure and keep expression, pattern and type trees, everything else already having a home in the compiler (in various tables), more or less. |
language constructs to the lowering step. Further in the future, the HIR should | ||
get more abstract and compact, and the AST should get closer to the surface | ||
syntax. | ||
|
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 RFC needs a kind of road-map of steps that need to be done (and each step should get an issue). It's too general right now.
- copy the AST to HIR after all AST transforms have been applied and have all other passes operate on the HIR
- remove some ast transforms
- remove
if let
ast transform and apply it during the AST -> HIR step - remove
while let
ast transform and apply it during the AST -> HIR step - remove
for
ast transform and apply it during the AST -> HIR step - cfg-attribute application step?
- erase all unresolved names from HIR and resolve names in the AST -> HIR step
- elide lifetimes in the AST -> HIR step and erase unresolved lifetimes from the HIR
- remove
- things that can be moved from tables to HIR
- i have no clue ;)
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.
The generalness is kind of deliberate. There's a lot we could do, what we actually do is down to prioritisation. Its also not clear how some of those steps tie into proposed work on reforming name resolution and syntax extensions. I hope this RFC spells out the first step and motivates it. Major stuff can get more RFCs (or some other kind of discussion) later.
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.
Ah that makes sense. Maybe that statement belongs into the RFC itself? :)
I think this is a very good idea. Most other successful compilers have at least one if not multiple successive lowerings ideally making the job of the following phases less complex. I was just talking to @nikomatsakis about this today in relation to implementing default type parameter fallback, it seems like we have a lot of relatively similar code scattered around the middle of the compiler because we are operating on the full language instead of a simplified restricted core. One advantage that comes to mind is the ability to type check functions and methods in a more uniform fashion. |
+1. This would be done at the "indexing ast" stage of course (after The AST is rather static these days, and breaking refactorings would be caught pretty quickly by the type-system. |
How about using this one as inspiration, it has some quite useful properties: |
@arielb1 I'm not worried about accidental breakage as much as having to modify several thousand lines. But seeing how HIR can be flattened and reduced to essentials, it's less of an issue. Speaking of which, the current I feel pretty good about flattening: resolve takes care of scoping, and we do preserve parent IDs already.
Another table-based resolve contortion is the "trait map" - each method call and non-qualified associated path is associated with a vector of traits in scope that contains an associated item with that name. |
Isn't that struct TraitItemRef(Name, ParamList); // ::Foo::<x_1,x_2>:: *item::<y_1,y_2>*
struct TraitRef(Ty, DefId, ParamList); // <T as Trait<..>> (or equiv. T: Trait<..>)
enum Path_ {
Static(Def, ParamList), // ::x::y::z::Foo::<x_1,x_2>
TypeItem(Ty, TraitItemRef), // <T>::Foo::<x_1,x_2> (or sugared T::Foo::<x_1,x_2>)
TraitItem(TraitRef, TraitItemRef) // <T as Trait>::Foo::<x_1,x_2>
// Trait::<x_1,x_2>::item is desugared as
// <_ as Trait<x_1,x_2>>::item
} Path resolution should take place within astconv, giving a |
I'm in favor of this plan. I think a lot of the interesting questions are in the details, of course, and in particular I think we have to be very careful about what we stabilize. Here are some thoughts:
|
Which part of resolve are you planning to route through the trait-system? I would prefer to at least handle locals in the HIR. |
Hear ye, hear ye. This RFC is now entering final comment period. |
@arielb1 what I was planning to do was to have resolve primarily concerned with expanding out the set of names mapped by use statements and so forth. Then when we encounter a path later, we can simply walk down and resolve it during type-checking, drawing on these tables. At that time we'll also have the information we need to complete UFCS resolution as well. |
I would prefer to remove all anonymous modules etc. in the HIR, keeping only the trait-import tables (as an |
+1 |
I'm generally in favor of this. I'd also like to see a mid-level IR that would permit more sophisticated desugaring/lowering where type information is needed, e.g. converting closures into structs. |
Huzzah! The compiler subteam has decided to accept this RFC. |
Add a high-level intermediate representation (HIR) to the compiler. This is
basically a new (and additional) AST more suited for use by the compiler.
This is purely an implementation detail of the compiler. It has no effect on the
language.
Note that adding a HIR does not preclude adding a MIR or LIR in the future.