-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
[10/n] Split constants and functions' arguments into disjoint bodies. #38449
Conversation
r? @arielb1 (rust_highfive has picked a reviewer for you, use r? to override) |
That sounds a bit troubling. |
@michaelwoerister AFAIK The rustdoc use is more problematic. I'm not sure there is a scenario in which it could go wrong, but long-term we should really move away from the current cross-crate docs model which is becoming unsustainable. I'm leaning towards the save-analysis solution, more so for rustdoc than IDEs even. |
Are you sure that compilation really aborts in case |
@michaelwoerister The information (argument names) is only used in case of (elision) error, later on (and printed verbatim, not used in any decision). |
I still think this is problematic. What you say might be true for now, but lots of people are modifying this code without global understanding. Can this be refactored to just access that information in case an actual error occurs? (Alternatively, for cases like this, we could have some opaque Regarding metadata: Isn't this kind of a premature optimization? Metadata is full of overconservative edges anyway. I think it would better to review this together with the rest when the time comes. Or does it break existing tests? |
@michaelwoerister Alright I'll try to see what I can do to |
Cool
I would prefer that too. I suspect we'll move away from monolithic As long as this is just used in rustdoc, we should be fine. How about just adding an assertion to |
Oh that is brilliant, thanks for the idea! I assume it would replace the usual |
Sounds reasonable. |
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.
Waiting on the commit to come. Looks good; we chatted about some of my comments on IRC. The thing about omitting the repeat expressions etc from borrowck is my biggest concern, though I'm not sure the best way to test it right now. Still seems like we should do it right.
|
||
use syntax::ast::*; | ||
use syntax::ext::hygiene::Mark; | ||
use syntax::visit; | ||
use syntax::symbol::{Symbol, keywords}; | ||
|
||
/// Creates def ids for nodes in the HIR. | ||
/// Creates def ids for nodes in the AST. |
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.
Did you intentionally change this from HIR to AST?
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.
Yeah, since it never touches the HIR anymore.
@@ -68,7 +68,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BorrowckCtxt<'a, 'tcx> { | |||
} | |||
|
|||
fn visit_fn(&mut self, fk: FnKind<'tcx>, fd: &'tcx hir::FnDecl, | |||
b: hir::ExprId, s: Span, id: ast::NodeId) { | |||
b: hir::BodyId, s: Span, id: ast::NodeId) { |
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 I can't find a way to make an error out of this (yet), but it seems like we are failing to borrowck embedded bodies -- e.g., in an expression like [22; X]
, we don't borrowck the expression X, right? The main reason I can't make an error here is that the set of constant expressions we accept in that context is pretty limited, but it seems like it wouldn't necessarily stay that way...
I did run across this, which seems like a bug, but a pre-existing one (this code compiles on nightly today...but it shouldn't...):
#![feature(const_fn)]
struct Foo(usize);
const fn get(x: Foo) -> usize {
x.0
}
const X: Foo = Foo(22);
static Y: usize = get(*&X);
fn main() {
}
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 shouldn't it? That's equivalent to ({*&Foo(22)}).0
which is perfectly fine AFAIK.
The problem would be if X
where static
(and only until we get miri).
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.
It should not because Foo
is not Copy
, and we are moving it from a &Foo
-- e.g., this does not compile: https://is.gd/zU2BVo
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.
Filed #38520
@@ -839,7 +839,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { | |||
_ => None, | |||
}, | |||
mir: match item.node { | |||
hir::ItemStatic(..) | | |||
hir::ItemStatic(..) if self.tcx.sess.opts.debugging_opts.always_encode_mir => { |
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.
was this just a pre-existing bug?
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.
Indeed it was, there were a few things in the PR introducing this that are less than ideal. They skipped review because they weren't in the original PR state but rather in "fixes for tests".
@@ -26,7 +26,9 @@ impl Foo for Def { | |||
|
|||
pub fn test<A: Foo, B: Foo>() { | |||
let _array: [u32; <A as Foo>::Y]; | |||
//~^ ERROR the trait bound `A: Foo` is not satisfied | |||
//~^ ERROR cannot use an outer type parameter in this context [E0402] |
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 there a backwards compatibility concern here? Probably not, since this sort of doesn't work now -- but I feel like it should work someday, so it seems odd to be considering A
as an "outer" type parameter.
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.
Yeah, I didn't really make anything worse, just better encoded the existing semantics.
We'll be able to clean this up in the future, when everything is body-based.
@@ -66,8 +66,10 @@ const CONST_CHANGE_TYPE_2: Option<u64> = None; | |||
const CONST_CHANGE_VALUE_1: i16 = 1; | |||
|
|||
#[cfg(not(cfail1))] | |||
#[rustc_dirty(label="Hir", cfg="cfail2")] | |||
#[rustc_clean(label="Hir", cfg="cfail2")] |
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.
👍
@@ -303,7 +303,7 @@ trait TraitChangeModeSelfOwnToMut: Sized { | |||
#[cfg(not(cfail1))] | |||
#[rustc_clean(label="Hir", cfg="cfail2")] | |||
#[rustc_clean(label="Hir", cfg="cfail3")] | |||
#[rustc_metadata_dirty(cfg="cfail2")] | |||
#[rustc_metadata_clean(cfg="cfail2")] |
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.
Can we make an ICH test targeting exactly this change? Seems easily do-able. In particular, if you have something like fn foo(x: u32) { }
and you change it to fn foo(y: u32) { }
, the hash of the trait should not change (just the body). Right?
That said, if you don't provide a default, based on my read of the code above, then the fn names would still be included in the hash... which doesn't seem exactly right. We could I guess just ignore them manually in the hasher code.
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.
That said, if you don't provide a default, based on my read of the code above, then the fn names would still be included in the hash... which doesn't seem exactly right.
To me this seems like the correct way to handle this. If you remove a method decl from a trait, don't you have to re-run many computations depending on that trait?
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 think @nikomatsakis meant the fn
argument names.
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.
Oh, that makes sense then.
☔ The latest upstream changes (presumably #38499) made this pull request unmergeable. Please resolve the merge conflicts. |
b7286b9
to
53e745b
Compare
This all looks good to me I think except that I'd still like to run borrowck expressions like the |
☔ The latest upstream changes (presumably #38154) made this pull request unmergeable. Please resolve the merge conflicts. |
31bd067
to
353a194
Compare
☔ The latest upstream changes (presumably #38479) made this pull request unmergeable. Please resolve the merge conflicts. |
@bors r=nikomatsakis |
📌 Commit ee0ea95 has been approved by |
⌛ Testing commit ee0ea95 with merge dd07f36... |
💔 Test failed - status-travis |
@bors retry |
[10/n] Split constants and functions' arguments into disjoint bodies. _This is part of a series ([prev](#38053) | [next]()) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well. If any motivation is unclear, please ask for additional PR description clarifications or code comments._ <hr> Finishes the signature-body split started in #37918, namely: * `trait` items are separated just like `impl` items were, for uniformity, closing #37712 * `static`s, `const`s (including associated ones), `enum` discriminants and array lengths get bodies * even the count in "repeat expressions", i.e. `n` in `[x; n]`, which fixes #24414 * arguments' patterns are moved to the bodies, with the types staying in `FnDecl` * `&self` now desugars to `self: &Self` instead of `self: &_` (similarly for other `self` forms) * `astconv`'s and metadata's (for rustdoc) informative uses are explicitly ignored for the purposes of the dep graph. this could be fixed in the future by hashing the exact information being extracted about the arguments as opposed to generating a dependency on *the whole body*
☀️ Test successful - status-appveyor, status-travis |
[11/n] Separate ty::Tables into one per each body. _This is part of a series ([prev](#38449) | [next]()) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. [MIR-based](https://github.com/solson/miri) early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well. If any motivation is unclear, please ask for additional PR description clarifications or code comments._ <hr> In order to track the results of type-checking and inference for incremental recompilation, they must be stored separately for each function or constant value, instead of lumped together. These side-`Tables` also have to be tracked by various passes, as they visit through bodies (all of which have `Tables`, even if closures share the ones from their parent functions). This is usually done by switching a `tables` field in an override of `visit_nested_body` before recursing through `visit_body`, to the relevant one and then restoring it - however, in many cases the nesting is unnecessary and creating the visitor for each body in the crate and then visiting that body, would be a much cleaner solution. To simplify handling of inlined HIR & its side-tables, their `NodeId` remapping and entries HIR map were fully stripped out, which means that `NodeId`s from inlined HIR must not be used where a local `NodeId` is expected. It might be possible to make the nodes (`Expr`, `Block`, `Pat`, etc.) that only show up within a `Body` have IDs that are scoped to that `Body`, which would also allow `Tables` to use `Vec`s. That last part also fixes #38790 which was accidentally introduced in a previous refactor.
This is part of a series (prev | next) of patches designed to rework rustc into an out-of-order on-demand pipeline model for both better feature support (e.g. MIR-based early constant evaluation) and incremental execution of compiler passes (e.g. type-checking), with beneficial consequences to IDE support as well.
If any motivation is unclear, please ask for additional PR description clarifications or code comments.
Finishes the signature-body split started in #37918, namely:
trait
items are separated just likeimpl
items were, for uniformity, closing Separate trait items from trait #37712static
s,const
s (including associated ones),enum
discriminants and array lengths get bodiesn
in[x; n]
, which fixes Improve "no type for local variable" error when in check_const_with_ty #24414FnDecl
&self
now desugars toself: &Self
instead ofself: &_
(similarly for otherself
forms)astconv
's and metadata's (for rustdoc) informative uses are explicitly ignored for the purposes of the dep graph. this could be fixed in the future by hashing the exact information being extracted about the arguments as opposed to generating a dependency on the whole body