-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
construct MIR for all crates up to and including rustdoc #27893
Conversation
cc @rust-lang/compiler |
r? @huonw (rust_highfive has picked a reviewer for you, use r? to override) |
@@ -479,6 +494,16 @@ pub trait Labeller<'a,N,E> { | |||
} | |||
} | |||
|
|||
/// Escape tags in such a way that it is suitable for inclusion in a | |||
/// Graphviz HTML label. | |||
pub fn escape_html(s: &str) -> String { |
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 isn't a great escape function, but I guess it's not really untrusted input.
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.
heh, yes. :)
The HIR in this patch is fairly distant from @nrc's HIR: his HIR is very close to the (expanded) syntax, and intended to separate type-checking from the details of expansion/resolution, while the HIR in this patch is more like an elaborated, desugared version of Rust. |
Vec { fields: Vec<ExprRef<H>> }, | ||
Tuple { fields: Vec<ExprRef<H>> }, | ||
Adt { adt_def: H::AdtDef, | ||
variant_index: usize, |
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.
why don't you store the variant itself?
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.
why don't you store the variant itself?
Because it was inconvenient to get from the variant to the containing enum and recompute its index, I think. Maybe I should just add those two bits of information to the VariantDef though.
Yes, sure. It may be that we evolve @nrc's HIR downwards (I hope we do), but in any case I agree they are not identical, though in my head they play pretty much the same role: a relatively high-level, AST-oriented view on Rust. Anyway I didn't see a suggestion for a better name in your comment. :P |
MHIR or HMIR? :p EDIT: Perhaps AIR, for Abstract Intermediate Representation. Or HAIR. |
EIR: Elevated Intermediate Representation... |
@glaebhoerl Her Majesty's Intermediate Representation? /British |
pub fn escape_html(s: &str) -> String { | ||
s | ||
.replace("\"", """) | ||
.replace("&", "&") |
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.
Always replace &
first, to avoid &quot;
.
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.
@glaebhoerl hmm, I do like "HAIR" :) |
} | ||
|
||
/// Compile `expr`, yielding a compile-time constant. Assumes that | ||
/// `expr` is a valid compile-time constant! |
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.
is the idea that after check_const
runs, everything marked as const will get turned into a const-rvalue?
I'd have thought the const-evaluator would be like an llvm-optimization-pass, simply running on the MIR without much more information (global consts + extern consts + const-fn are needed of course).
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.
@oli-obk I started writing a response and found I had more to say than seemed appropriate for a GitHub comment. See this thread: https://internals.rust-lang.org/t/how-to-handle-constants-in-the-compiler/2543
Use(Lvalue<H>), | ||
|
||
// [x; 32] | ||
Repeat(Lvalue<H>, Lvalue<H>), |
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.
so the second value should be a Constant<H>
?
Hmm, yes, I see, I see. Of course I copied this approach from how trans does things, but I agree it's not right. I'm modifying the MIR construction now, but it seems to push me more in favor of introducing an |
fe02dd8
to
107f822
Compare
OK, I just did a major rebase that folded in all of the WIP comments. In particular I introduced a new concept into the MIR,
It also means we do NOT introduce temporaries for constants in expressions like It seems like these properties are worthy of unit testing, so I may turn some attention to how we can build up a unit test framework. That said, introducing the notion of Also, it should be no problem to purge unnecessary temporaries later, once we have ascertained for sure that there is no mutation to the source of the temporary. As @arielb1 said, I'd rather do that in a separate, dedicated pass (this can also cover the optimizations around pattern matching we now do in trans, I imagine.) This may be worth updating the RFC for as well, since it marks the first departure, but I'll hold off on that. (And the RFC was clearly intended to evolve anyhow.) |
☔ The latest upstream changes (presumably #27943) made this pull request unmergeable. Please resolve the merge conflicts. |
|
||
#[derive(Clone, PartialEq)] | ||
pub enum Operand<H:HIR> { | ||
Lvalue(Lvalue<H>), |
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'd almost want to name this variant Move
or Consume
.
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.
Of course this won't do the decision-tree optimizations, but the temporary-elimination optimizations we do in trans are basically the reverse of RVO. We translate code like match foo {
Some(foo_inner) => return Some(f(foo_inner));
None => return None
} into MIR (sugared-assmebly-format, rather than graph-format, temporaries are
Standard RVO would replaces temporaries that are written somewhere with the place they are written to:
Match optimization substitutes temporaries with their values
|
Maybe DVIR (desugared value-level IR) for the "HIR"? |
Yes, this is what I meant. |
2cee71c
to
d44473b
Compare
this serves as a poor man's unit test infrastructure until MIR is more built up
works around a stage0 bug that has since been fixed.
@bors try |
⌛ Trying commit 2f00086 with merge ea3892f... |
This PR contains a new crate, `rustc_mir`, which implements the MIR as specified in the RFC (more or less). There are no targeted unit tests at the moment, as I didn't decide what kind of infrastructure would be best and didn't take the time to implement it. ~~NB: In packaging up this PR, I realized that MIR construction code is not triggering for methods right now, I think it's only for fixed fns. I'll push a fix for this soon. Hopefully it doesn't stop any crates from building. :)~~ Fixed. Everything still seems to work. However, the MIR construction code (`librustc_mir/build`) is intentionally quite distinct from the code which munges the compiler's data structures (`librustc_mir/tcx`). The interface between the two is the `HIR` trait (`librustc_mir/hir`). To avoid confusion with @nrc's work, perhaps a better name for this trait is warranted, although ultimately this trait *will* be connected to the HIR, I imagine, so in a way the name is perfect. Anyway, I'm open to suggestions. The initial motivation for this split was to allow for the MIR construction code to be unit-tested. But while I didn't end up writing unit tests (yet), I did find the split made the code immensely easier to think about, since the messiness of our existing system, with its myriad hashtables, punning, and so forth, is confined to one part, which simply transforms to a more fully explicit AST-like form. I tried to separate out the commits somewhat, but since this mostly new code, it mostly winds up coming in one fell swoop in the MIR commit. Quick guide to the MIR crate: - `repr.rs` defines the MIR itself; each MIR instance is parameterized by some HIR `H` - `build/` is the MIR construction code, parameterized by a particular HIR - `hir/` is the definition of the HIR interface - `tcx/` is the impl of the HIR interface for the tcx - `dump.rs` is the minimal compiler pass that invokes the HIR One open question: - In the HIR trait, I used exclusively struct-like variants. I found I like this more, since things have names. Should I convert the repr code?
📌 Commit 2f00086 has been approved by |
@bors r=nrc |
📌 Commit c8a6618 has been approved by |
This PR contains a new crate, `rustc_mir`, which implements the MIR as specified in the RFC (more or less). There are no targeted unit tests at the moment, as I didn't decide what kind of infrastructure would be best and didn't take the time to implement it. ~~NB: In packaging up this PR, I realized that MIR construction code is not triggering for methods right now, I think it's only for fixed fns. I'll push a fix for this soon. Hopefully it doesn't stop any crates from building. :)~~ Fixed. Everything still seems to work. However, the MIR construction code (`librustc_mir/build`) is intentionally quite distinct from the code which munges the compiler's data structures (`librustc_mir/tcx`). The interface between the two is the `HIR` trait (`librustc_mir/hir`). To avoid confusion with @nrc's work, perhaps a better name for this trait is warranted, although ultimately this trait *will* be connected to the HIR, I imagine, so in a way the name is perfect. Anyway, I'm open to suggestions. The initial motivation for this split was to allow for the MIR construction code to be unit-tested. But while I didn't end up writing unit tests (yet), I did find the split made the code immensely easier to think about, since the messiness of our existing system, with its myriad hashtables, punning, and so forth, is confined to one part, which simply transforms to a more fully explicit AST-like form. I tried to separate out the commits somewhat, but since this mostly new code, it mostly winds up coming in one fell swoop in the MIR commit. Quick guide to the MIR crate: - `repr.rs` defines the MIR itself; each MIR instance is parameterized by some HIR `H` - `build/` is the MIR construction code, parameterized by a particular HIR - `hir/` is the definition of the HIR interface - `tcx/` is the impl of the HIR interface for the tcx - `dump.rs` is the minimal compiler pass that invokes the HIR One open question: - In the HIR trait, I used exclusively struct-like variants. I found I like this more, since things have names. Should I convert the repr code?
Remove unnecessary FIXME Found this while browsing rustc, I traced it back to rust-lang#27893 when MIR first introduced, some time passed since then and I think this FIXME is no longer necessary.
This PR contains a new crate,
rustc_mir
, which implements the MIR as specified in the RFC (more or less). There are no targeted unit tests at the moment, as I didn't decide what kind of infrastructure would be best and didn't take the time to implement it.NB: In packaging up this PR, I realized that MIR construction code is not triggering for methods right now, I think it's only for fixed fns. I'll push a fix for this soon. Hopefully it doesn't stop any crates from building. :)Fixed. Everything still seems to work.However, the MIR construction code (
librustc_mir/build
) is intentionally quite distinct from the code which munges the compiler's data structures (librustc_mir/tcx
). The interface between the two is theHIR
trait (librustc_mir/hir
). To avoid confusion with @nrc's work, perhaps a better name for this trait is warranted, although ultimately this trait will be connected to the HIR, I imagine, so in a way the name is perfect. Anyway, I'm open to suggestions. The initial motivation for this split was to allow for the MIR construction code to be unit-tested. But while I didn't end up writing unit tests (yet), I did find the split made the code immensely easier to think about, since the messiness of our existing system, with its myriad hashtables, punning, and so forth, is confined to one part, which simply transforms to a more fully explicit AST-like form. I tried to separate out the commits somewhat, but since this mostly new code, it mostly winds up coming in one fell swoop in the MIR commit.Quick guide to the MIR crate:
repr.rs
defines the MIR itself; each MIR instance is parameterized by some HIRH
build/
is the MIR construction code, parameterized by a particular HIRhir/
is the definition of the HIR interfacetcx/
is the impl of the HIR interface for the tcxdump.rs
is the minimal compiler pass that invokes the HIROne open question: