-
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
Don't drag function signatures along function item types. #42417
Conversation
substs.fold_with(folder), | ||
f.fold_with(folder)) | ||
ty::TyFnDef(def_id, substs) => { | ||
ty::TyFnDef(def_id, substs.fold_with(folder)) |
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 it okay that signatures are not folded anymore? (Is it possible to fold something kept in the tables at all?)
It would be really nice if they were at least still visited by default.
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 whole point (which I'll try to describe once I'm sure there's no fatal flaw with the approach) is to reduce the amount of work done for these types. Anything that relied on seeing the signature has to visit it manually. It's not a property of the type and it was never meant to be, it's just one way to use values of that type (i.e. calling them).
@bors try This will get us artifacts for cargobomb. |
⌛ Trying commit 198067e with merge c7ced21... |
💔 Test failed - status-travis |
Don't retry until the previous try finishes one way or another. |
@bors try |
⌛ Trying commit 87a65f2 with merge ebf4c15... |
Oh right @bors retry |
⌛ Trying commit 87a65f2 with merge ab0e704... |
☔ The latest upstream changes (presumably #42362) made this pull request unmergeable. Please resolve the merge conflicts. |
Started crater run (fingers crossed it's fixed now). |
@bors try |
1 similar comment
@bors try |
Don't drag function signatures along function item types. **TODO**: write description (made PR for crater/cargobomb shenanigans) r? @nikomatsakis
I've started a cargobomb run of this. |
💥 Test timed out |
☔ The latest upstream changes (presumably #42504) made this pull request unmergeable. Please resolve the merge conflicts. |
@bors r+ |
📌 Commit 69076f3 has been approved by |
Don't drag function signatures along function item types. This PR separates the signature of a function from the "function item type" (`TyFnDef`), leaving only the `DefId` and parameter `Substs`, making them even more like (captureless) closure types. The motivation for this change is reducing typesystem complexity, and its consequences: * operating on the signature instead of just the parameters was less efficient * specifically, signatures can easily add several levels of depth on top of the parameter types * and the signatured were always substituted and normalized, so typically even more complex * it was *the only* type that was *both* nominal (identity) and structural (signature) * harder to model in Chalk than either a purely nominal or structural type * subtyping worked on the signature but parameters were always invariant * call type-checking was transforming signatures but keeping the nominal half intact * the signature could therefore get out of sync during type inference in several ways That last point comes with a `[breaking-change]`, because functions with `'static` in their return types will now *not* be as usable as if they were using lifetime parameters instead: ```rust // Will cause lifetime mismatch in main after this PR. fn bar() -> &'static str { "bar" } // Will continue to work fine, as every use can choose its own lifetime. fn bar<'a>() -> &'a str { "bar" } fn main() { let s = String::from("foo"); Some(&s[..]).unwrap_or_else(bar); } ``` r? @nikomatsakis
☀️ Test successful - status-appveyor, status-travis |
This is stabilizing in 1.20 (Thursday). I realize this is probably a little late, but can we add a better error message when people encounter this breaking change? You now just get a generic borrow check error. Easy to test with the example from the first PR comment. |
@jethrogb Are you talking about the example itself or have you seen this in the wild in another form? And no, you can't detect this without reintroducing the complex representation removed here. |
@eddyb I just came here from the draft release notes. I haven't actually encountered any broken code myself. I do think it's fairly common for people to write I don't exactly understand how this change makes detecting this harder but maybe some kind of heuristic (instead of a guaranteed detection) is good enough. Alternatively, maybe we can make a documentation change somewhere. |
You only get an error if you pass such a function to another function that usually takes a closure. |
I meant this is a way to fix the code above: Some(&s[..]).unwrap_or_else(||&*bar()); |
Oh and the canonical fix is to make the |
Sure but the user doesn't always have a choice in that regard. Popular crates use |
Fair enough, the second best choice is introducing a closure (like you did, if you ignore the reborrow). |
This PR separates the signature of a function from the "function item type" (
TyFnDef
), leaving only theDefId
and parameterSubsts
, making them even more like (captureless) closure types.The motivation for this change is reducing typesystem complexity, and its consequences:
That last point comes with a
[breaking-change]
, because functions with'static
in their return types will now not be as usable as if they were using lifetime parameters instead:r? @nikomatsakis