Skip to content
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

Refactor fallback code to prepare for never type #88149

Merged
merged 8 commits into from
Aug 21, 2021

Conversation

Mark-Simulacrum
Copy link
Member

This PR contains cherry-picks of some of @nikomatsakis's work from #79366, and shouldn't (AFAICT) represent any change in behavior. However, the refactoring is good regardless of the never type work being landed, and will reduce the size of those eventual PR(s) (and rebase pain).

I am not personally an expert on this code, and the commits are essentially 100% @nikomatsakis's, but they do seem reasonable to me by my understanding. Happy to edit with review, of course. Commits are best reviewed in sequence rather than all together.

r? @jackh726 perhaps?

@rust-highfive
Copy link
Collaborator

Some changes occurred in src/tools/clippy.

cc @rust-lang/clippy

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 19, 2021
Copy link
Member

@jackh726 jackh726 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, the changes here are pretty simple. Have a few comments/thoughts, but I'd like to take another pass before r+ing.

compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs Outdated Show resolved Hide resolved
compiler/rustc_middle/src/ty/mod.rs Outdated Show resolved Hide resolved
compiler/rustc_middle/src/ty/mod.rs Show resolved Hide resolved
// Note that we can just skip the binders here because
// type variables can't (at present, at
// least) capture any of the things bound by this binder.
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Do we really need the extra brackets?

let r_b = self.shallow_resolve(predicate.skip_binder().b);
match (r_a.kind(), r_b.kind()) {
(&ty::Infer(ty::TyVar(a_vid)), &ty::Infer(ty::TyVar(b_vid))) => {
self.inner.borrow_mut().type_variables().sub(a_vid, b_vid);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious what the diagnostics look like without this.

compiler/rustc_infer/src/infer/sub.rs Show resolved Hide resolved
compiler/rustc_typeck/src/check/fallback.rs Show resolved Hide resolved
We used to avoid doing this because we didn't want to make coercion depend on
the state of inference. For better or worse, we have moved away from this
position over time. Therefore, I am going to go ahead and resolve the `b`
target type early on so that it is done uniformly.

(The older technique for managing this was always something of a hack
regardless; if we really wanted to avoid integrating coercion and inference we
needed to be more disciplined about it.)
@Mark-Simulacrum
Copy link
Member Author

Force-pushed squashed in fixes to your current comments (since they were all mostly "nit"-like).

As I read through the commits, I'm curious how this will get used.

https://gist.github.com/nikomatsakis/7a07b265dc12f5c3b3bd0422018fa660 is a pretty good write up of the "v1" algorithm proposed for landing never type. There's some additional extensions that are currently suggested in #84573 to mitigate some of the cases v1 doesn't address, but those are about detecting particular edge cases really.

The goal of the coercion predicates in particular is to build up the coercion graph added in the commits after these ~8 in #84573, which is an attempt to track the "liveness" of particular type variables during fallback.

I'm curious what the diagnostics look like without this.

You can see a diff here - acd7444 -- nothing obviously major either way, though issue-57843 under NLL interestingly compiles without errors?

@jackh726
Copy link
Member

Yes, I started to go back and read through the write up.

It's really interesting that issue-57843 compiles in nll without that extra sub. (Actually, I feel like the behavior with the change is more of what we want, but it's still a change). This makes me a bit suspicious. At the very least the comments need to be changed to address that it's not purely diagnostics. Maybe @nikomatsakis might be interested or have thoughts.

(P.s. I think it's funny and a nice coincidence how similar 84573 and 57843 are to each other)

@jackh726
Copy link
Member

jackh726 commented Aug 20, 2021

@Mark-Simulacrum 536da6f can be removed in isolation, right? If you can remove that, then r=me on this. Given that it does not end up as purely diagnostics changes, I'm more wary to approve that right now. Given that everything else is straightforward, I wouldn't one that one commit to up the whole PR.

So, r=me on the other 7 commits.

We can discuss that commit in a separate PR?

@rust-log-analyzer

This comment has been minimized.

@jackh726
Copy link
Member

jackh726 commented Aug 20, 2021

Ah interesting. Seems less straightforward than I thought. In this case, I'm fine with adding the commit back in with a proper comment that the extra sub is not only for diagnostics but may have semantic effects.

r=me with that

I didn't like the sub-unify code executing when a predicate was
ENQUEUED, that felt fragile. I would have preferred to move the
sub-unify code so that it only occurred during generalization, but
that impacted diagnostics, so having it also occur when we process
subtype predicates felt pretty reasonable. (I guess we only need one
or the other, but I kind of prefer both, since the generalizer
ultimately feels like the *right* place to guarantee the properties we
want.)
Motivation: in upcoming commits, we are going to create a graph of the
coercion relationships between variables. We want to
distinguish *coercion* specifically from other sorts of subtyping, as
it indicates values flowing from one place to another via assignment.
Along the way, simplify and document the logic more clearly.
@Mark-Simulacrum
Copy link
Member Author

Added the note here 020655b#diff-79cce3ca916fa3f7d4f1b1879dbec1b3852414a5cfc719087851635aaa240a97R1018-R1019, will see if CI is passing (just in case, though it really should).

@Mark-Simulacrum
Copy link
Member Author

@bors r=jackh726

@bors
Copy link
Contributor

bors commented Aug 20, 2021

📌 Commit 60cc00f has been approved by jackh726

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 20, 2021
@Mark-Simulacrum
Copy link
Member Author

@bors rollup=never in case this has perf effects, though we don't really expect it. touches some possibly sensitive code though.

@bors
Copy link
Contributor

bors commented Aug 21, 2021

⌛ Testing commit 60cc00f with merge 797095a...

@bors
Copy link
Contributor

bors commented Aug 21, 2021

☀️ Test successful - checks-actions
Approved by: jackh726
Pushing 797095a to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 21, 2021
@bors bors merged commit 797095a into rust-lang:master Aug 21, 2021
@rustbot rustbot added this to the 1.56.0 milestone Aug 21, 2021
JohnTitor added a commit to JohnTitor/rust-semverver that referenced this pull request Oct 13, 2021
@Mark-Simulacrum Mark-Simulacrum deleted the prep-never-type branch January 3, 2022 23:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants