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

Matthew's work on improving NLL's "higher-ranked subtype error"s #86700

Merged
merged 13 commits into from
Aug 18, 2021

Conversation

lqd
Copy link
Member

@lqd lqd commented Jun 28, 2021

This PR rebases @matthewjasper's branch which has great work to fix the obscure higher-ranked subtype errors that are tracked in #57374.

These are a blocker to turning full NLLs on, and doing some internal cleanups to remove some of the old region code.

The goal is so @nikomatsakis can take a look at this early, and I'll then do my best to help do the changes and followup work to land this work, and move closer to turning off the migration mode.

I've only updated the branch and made it compile, removed a warning or two.

r? @nikomatsakis

(Here's the zulip topic to discuss this that Niko wanted)

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

@estebank estebank left a comment

Choose a reason for hiding this comment

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

I'm still looking at the two big "adding" files, but otherwise it looks great so far! Only a couple of nitpicks that I noticed, but very little that would need addressing on this PR.

| ^^^^^^^ one type is more general than the other
|
= note: expected type `&'a ()`
found reference `&()`
Copy link
Contributor

Choose a reason for hiding this comment

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

It would be nice if we could reach parity with the non-nll output:

error[E0308]: mismatched types
  --> $DIR/higher-ranked-projection.rs:25:5
   |
LL |     foo(());
   |     ^^^ lifetime mismatch
   |
   = note: expected type `&'a ()`
              found type `&()`
note: the lifetime requirement is introduced here
  --> $DIR/higher-ranked-projection.rs:15:33
   |
LL |     where for<'a> &'a T: Mirror<Image=U>
   |                                 ^^^^^^^

Copy link
Member Author

@lqd lqd Jul 12, 2021

Choose a reason for hiding this comment

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

I have some good news and less good news here. The good news is, this PR uses basically the same piece of code that emits the error above, the "nice region errors" (I take that back the error above is not a nice region error 😅 but some of the others in the blessed test expectations are), so it's at least not impossible to reach parity. I believe this was purposeful and one of Matthew's goals (I'm only the slightly-informed messenger here).

The "bad" news is the data: I don't think I have access to the actual same ObligationCauses in this case (or couldn't find them when I looked) so if you or @nikomatsakis (I know he won't see this notification, it's more of a message for when/if he also reviews this PR) can point me in the right direction to add them, I'll be glad to work on this more.

To be more specific, the migrate-mode error note above is emitted by report_placeholder_failure which specifically looks for a BindingObligation cause.

With this PR, this is an UpperBoundUniverseConflict but with types value pairs, so the nice region error is not actually emitted as these placeholder conflicts are only about placeholder and traits mismatches. The obligation available is however a MiscObligation here. (I believe it's this dummy one).

Funnily enough, report_placeholder_failure would emit what this PR emits, in such fallback cases.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm. I'm not sure off hand how to get that obligation cause, it's probably going to take a bit of threading.

Copy link
Member Author

Choose a reason for hiding this comment

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

Understood, thank you. I will look into it when I can.

Do you and @estebank agree that we could leave this topic for follow-up improvement PRs ? (Esteban has mentioned this on other suggestions, and I presume it would be ok for this suggestion as well)

Copy link
Contributor

Choose a reason for hiding this comment

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

As long as we don't turn NLL on without addressing this, I'm ok with it.

--> $DIR/issue-59311.rs:17:9
|
LL | v.t(|| {});
| ^^^^^
|
= note: could not prove for<'a> &'a V: 'static
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally we would point at the where clause as well. (not for this PR)

Copy link
Member

Choose a reason for hiding this comment

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

This should not actually be an error - see #89409. However, it occurs both with and without #![feature(nll)], so I don't think we need to address this before turning on NLL mode.

Comment on lines +7 to +8
= note: `SomeStruct` must implement `Foo<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
= note: ...but it actually implements `Foo<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally we would point at the impl and the where clause in want_foo2.

Copy link
Member

Choose a reason for hiding this comment

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

In both NLL and non-nll mode, we don't point at the impl or where clause. I think this could be an separate diagnostics issue, independent of the NLL transition.

compiler/rustc_mir/src/borrow_check/region_infer/values.rs Outdated Show resolved Hide resolved
Comment on lines 95 to 97
fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> {
if let Some(borrowck_context) = &mut self.borrowck_context {
borrowck_context.constraints.placeholder_region(self.infcx, placeholder)
} else {
self.infcx.tcx.lifetimes.re_erased
}
self.borrowck_context.constraints.placeholder_region(self.infcx, placeholder)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This change doesn't break anything?

Copy link
Member Author

@lqd lqd Jul 12, 2021

Choose a reason for hiding this comment

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

I don't expect it to, this Option was only used with a Some, but it's easier to see in the individual commit

Copy link
Contributor

@nikomatsakis nikomatsakis left a comment

Choose a reason for hiding this comment

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

OK, I reviewed the PR. I understand what it's doing. I'm mildly worried about the lack of DRY, though, I'd like it if it the query impl and the code to "re-run the query and report errors" were combined more clearly-- or at least in the same file or something!

I'm imagining it's probably possible to have some kind of helper function that both of them can call?

placeholder_region: ty::Region<'tcx>,
error_region: Option<ty::Region<'tcx>>,
) -> Option<DiagnosticBuilder<'tcx>> {
tcx.infer_ctxt().enter_with_canonical(span, &self.canonical_query, |ref infcx, key, _| {
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, this seems awfully "non-DRY", right? It'd be nice if this shared some of the same code as the query itself..?

Copy link
Member Author

@lqd lqd Aug 15, 2021

Choose a reason for hiding this comment

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

On the one hand, I agree the duplication is to be avoided, so I added a helper function to share most of the query code for type_op_prove_predicate. Let me know if that's more to your liking.

On the other hand, these type op queries are super small and have not changed in the last 3 years, and since the normalize step to get the obligations in the diagnostics is different from the query's, I have not done this for the other type op type_op::Normalize: it would only de-dupe a single register_predicate_obligations call.

I think the functional difference between the two is the query fails to normalize this (but maybe it's some subtle interaction with the leak-check there, or maybe the difference would be erased by some of the fixes in #85499, I don't know).

I can add a FIXME to at least track this in the list of remaining tasks to be done to turn full NLLs on, if that's OK with you ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, that's ok

| ^^^^^^^ one type is more general than the other
|
= note: expected type `&'a ()`
found reference `&()`
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm. I'm not sure off hand how to get that obligation cause, it's probably going to take a bit of threading.

@bjorn3 bjorn3 mentioned this pull request Aug 5, 2021
@bors

This comment has been minimized.

Copy link
Contributor

@matthewjasper matthewjasper left a comment

Choose a reason for hiding this comment

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

Thanks for pushing this forwards.

{
fn to_universe_info(self, _base_universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
// Ascribe user type isn't usually called on types that have different
// bound regions.
Copy link
Contributor

Choose a reason for hiding this comment

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

Note for a future PR: I believe there is one test case that is affected by this

Copy link
Member Author

Choose a reason for hiding this comment

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

Maybe it was in one of the last few remaining instances of the old "higher-ranked subtype" errors involving type ascription ?

  1. hrtb/due-to-where-clause.rs
  2. hrtb-cache-issue-54302.rs
  3. hrtb-just-for-static.rs
  4. issue-54302.rs

Copy link
Contributor

Choose a reason for hiding this comment

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

After checking this, it's all of those.

Co-authored-by: matthewjasper <20113453+matthewjasper@users.noreply.github.com>
@nikomatsakis
Copy link
Contributor

@bors r+

@bors
Copy link
Contributor

bors commented Aug 17, 2021

📋 Looks like this PR is still in progress, ignoring approval.

Hint: Remove [WIP] from this PR's title when it is ready for review.

@nikomatsakis
Copy link
Contributor

r=me @lqd when not WIP :)

@lqd lqd changed the title [WIP] Matthew's work on improving NLL's "higher-ranked subtype error"s Matthew's work on improving NLL's "higher-ranked subtype error"s Aug 18, 2021
@lqd
Copy link
Member Author

lqd commented Aug 18, 2021

WIP removed, FIXME added. I'll trigger bors once CI passes.

@lqd
Copy link
Member Author

lqd commented Aug 18, 2021

@bors r=nikomatsakis

I'll update the tracking issue to mention the actual state of the errors, and the known work remaining to be done (matching the non-NLL output, cleaning up the normalize type op query, improve errors for the type ascription type op query as Matthew mentioned)

@bors
Copy link
Contributor

bors commented Aug 18, 2021

📌 Commit 8343806 has been approved by nikomatsakis

@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 18, 2021
@bors
Copy link
Contributor

bors commented Aug 18, 2021

⌛ Testing commit 8343806 with merge 3d0774d...

@bors
Copy link
Contributor

bors commented Aug 18, 2021

☀️ Test successful - checks-actions
Approved by: nikomatsakis
Pushing 3d0774d to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Aug 18, 2021
@bors bors merged commit 3d0774d into rust-lang:master Aug 18, 2021
@rustbot rustbot added this to the 1.56.0 milestone Aug 18, 2021
@lqd lqd deleted the matthews-nll-hrtb-errors branch August 18, 2021 18:48
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Aug 26, 2021
…sakis

Handle type ascription type ops in NLL HRTB diagnostics

Currently, there are still a few cases of the "higher-ranked subtype error" of yore, 4 of which are related to type ascription.

This PR is a follow-up to rust-lang#86700, adding support for type ascription type ops, and makes 3 of these tests output the same diagnostics in NLL mode as the migrate mode (and 1 is now much closer, especially if you ignore that it already outputs an additional error in NLL mode -- which could be a duplicate caused by a lack of normalization like [these comments point out](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/compiler/rustc_traits/src/type_op.rs#L122-L157), or an imprecision in some parts of normalization as [described here](rust-lang#86700 (comment))).

Since we discussed these recently:
- [here](rust-lang#86700 (comment)), cc `@matthewjasper,`
- and [here](rust-lang#57374 (comment)), cc `@Aaron1011.`

It should only leave [this TAIT test](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs) as still emitting [the terse error](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr).

r? `@estebank` (so that they shake their fist at NLL's general direction less often) or `@nikomatsakis` or matthew or aaron, the more the merrier.
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Aug 26, 2021
…sakis

Handle type ascription type ops in NLL HRTB diagnostics

Currently, there are still a few cases of the "higher-ranked subtype error" of yore, 4 of which are related to type ascription.

This PR is a follow-up to rust-lang#86700, adding support for type ascription type ops, and makes 3 of these tests output the same diagnostics in NLL mode as the migrate mode (and 1 is now much closer, especially if you ignore that it already outputs an additional error in NLL mode -- which could be a duplicate caused by a lack of normalization like [these comments point out](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/compiler/rustc_traits/src/type_op.rs#L122-L157), or an imprecision in some parts of normalization as [described here](rust-lang#86700 (comment))).

Since we discussed these recently:
- [here](rust-lang#86700 (comment)), cc ``@matthewjasper,``
- and [here](rust-lang#57374 (comment)), cc ``@Aaron1011.``

It should only leave [this TAIT test](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs) as still emitting [the terse error](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr).

r? ``@estebank`` (so that they shake their fist at NLL's general direction less often) or ``@nikomatsakis`` or matthew or aaron, the more the merrier.
Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this pull request Aug 26, 2021
…sakis

Handle type ascription type ops in NLL HRTB diagnostics

Currently, there are still a few cases of the "higher-ranked subtype error" of yore, 4 of which are related to type ascription.

This PR is a follow-up to rust-lang#86700, adding support for type ascription type ops, and makes 3 of these tests output the same diagnostics in NLL mode as the migrate mode (and 1 is now much closer, especially if you ignore that it already outputs an additional error in NLL mode -- which could be a duplicate caused by a lack of normalization like [these comments point out](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/compiler/rustc_traits/src/type_op.rs#L122-L157), or an imprecision in some parts of normalization as [described here](rust-lang#86700 (comment))).

Since we discussed these recently:
- [here](rust-lang#86700 (comment)), cc ```@matthewjasper,```
- and [here](rust-lang#57374 (comment)), cc ```@Aaron1011.```

It should only leave [this TAIT test](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs) as still emitting [the terse error](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr).

r? ```@estebank``` (so that they shake their fist at NLL's general direction less often) or ```@nikomatsakis``` or matthew or aaron, the more the merrier.
Manishearth added a commit to Manishearth/rust that referenced this pull request Aug 26, 2021
…sakis

Handle type ascription type ops in NLL HRTB diagnostics

Currently, there are still a few cases of the "higher-ranked subtype error" of yore, 4 of which are related to type ascription.

This PR is a follow-up to rust-lang#86700, adding support for type ascription type ops, and makes 3 of these tests output the same diagnostics in NLL mode as the migrate mode (and 1 is now much closer, especially if you ignore that it already outputs an additional error in NLL mode -- which could be a duplicate caused by a lack of normalization like [these comments point out](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/compiler/rustc_traits/src/type_op.rs#L122-L157), or an imprecision in some parts of normalization as [described here](rust-lang#86700 (comment))).

Since we discussed these recently:
- [here](rust-lang#86700 (comment)), cc ````@matthewjasper,````
- and [here](rust-lang#57374 (comment)), cc ````@Aaron1011.````

It should only leave [this TAIT test](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.rs) as still emitting [the terse error](https://github.com/rust-lang/rust/blob/9583fd1bdd0127328e25e5b8c24dff575ec2c86b/src/test/ui/type-alias-impl-trait/issue-57611-trait-alias.nll.stderr).

r? ````@estebank```` (so that they shake their fist at NLL's general direction less often) or ````@nikomatsakis```` or matthew or aaron, the more the merrier.
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.

None yet

8 participants