Do proper signature equality checking for tail calls#156007
Do proper signature equality checking for tail calls#156007WaffleLapkin wants to merge 8 commits into
Conversation
This comment has been minimized.
This comment has been minimized.
| become foo(x, y); | ||
| //~^ ERROR mismatched signatures | ||
| //[current]~^ ERROR mismatched signatures | ||
| } |
There was a problem hiding this comment.
There was a problem hiding this comment.
I'm not quite sure (lcnr can probably explain better), but something something opaque types are more annoying to handle in the old solver and in this case they are not being revealed as their hidden type.
There was a problem hiding this comment.
the main issue is that the old solver does not have a way to say "we're in the defining scope of the following opaque types and have already inferred their hidden types".
So while you can kind of hack around this by allowing them to be redefined and then checking that they match the actually inferred value, this is annoying and doesn't fully work. This is what check_opaque_type_well_formed (I think that's what the method is called) does
3371ceb to
0ef36d2
Compare
This comment has been minimized.
This comment has been minimized.
15bd832 to
1ce7add
Compare
1ce7add to
6623564
Compare
6623564 to
1ddb39e
Compare
This comment has been minimized.
This comment has been minimized.
1ddb39e to
cf7e816
Compare
cf4857c to
27c59a3
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
27c59a3 to
f184753
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
f184753 to
e35a777
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
e35a777 to
b4e1514
Compare
| let callee_sig = callee_sig.set_safety(Safety::Safe); | ||
|
|
||
| if let Err(_e) = | ||
| infcx.at(&cause, param_env).sub(DefineOpaqueTypes::No, caller_sig, callee_sig) |
There was a problem hiding this comment.
this ignores nested obligations of the equality, and region constraints
let ocx = ObligationCtxt::new(&infcx); ocx.sub;
and then handle pending obligations and region constraints
There was a problem hiding this comment.
Region constraints are ignored on purpose:
// Checks that the signatures of the caller and callee match (as a proxy to check that they // are ABI compatible and tail calls can always happen). // // This ignores lifetimes and safety, as those do not affect ABI.
Re: nested obligations, I can't come up with an example that requires them. I.e. I can change this to use ocx, but I can't seem to make a test that would fail with the current code...
There was a problem hiding this comment.
Looking at rustc_type_ir/src/relate/solver_relating.rs, the only code path that modifies SolverRelating::goals are relating of two inference variables... but there can be no inference variables at this point afaik -- this is called after type checking and all types should be known by now.
There was a problem hiding this comment.
we also emit nested goals when encountering non-rigid aliases 🤔
// This ignores lifetimes and safety, as those do not affect ABI.
you need to consider lifetimes to correctly handle higher-ranked regions as these can impact TypeId and layout
I think in practice you could limit yourself to only a leak check and ignore constraints between free regions, I don't fully trust that until Boxy's assumptions on binders work is done
There was a problem hiding this comment.
I added a commit to use ocx, but still have 0 clue how to construct any tests which fail without this change...
View all comments
For tail calls to be valid, we need some support from the ABI, specifically the caller of the function needs to be able to do all necessary cleanup after the tail called function returns. This can be achieved with a callee-cleanup ABI, but we want to permit tail calls for other ABIs as well (in particular,
extern "rust").In such cases the property that we are looking for is "the caller and callee require the same cleanup". We approximate this with "caller and callee have the same ABI" and we approximate that with "caller and callee have the same signatures (modulo subtyping)".
Previously the code would compare
FnSigs with==, which would not support subtyping and produced other weird results. This PR changes tail call checks to use type checking machinery and in particulareq.It also fixes handling of opaque types, given the next trait solver is enabled.
r? types