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

revealing uses in the defining scope: merge borrowck for all typeck children #129

Closed
1 of 3 tasks
lcnr opened this issue Jan 28, 2025 · 3 comments
Closed
1 of 3 tasks
Labels
final-comment-period The FCP has started, most (if not all) team members are in agreement major-change A major change proposal to-announce Announce this issue on triage meeting

Comments

@lcnr
Copy link
Contributor

lcnr commented Jan 28, 2025

Proposal

One of the main remaining blockers of the next-generation trait solver is our handling of opaque types. The core issue is that there are many existing uses of RPITs which are opaque with the existing impl but will reveal the opaque type with the new solver.

Background

Consider the following example, minimized from the gll crate:

struct Foo;
impl Foo {
    fn defines_rpit(&self) -> impl Sized + '_ {
        let _ = || {
            let temp = Foo;
            temp.defines_rpit();
            // desugars to `Foo::defines_rpit(&temp);`
        };

        self
    }
}

The recursive function call currently does not reveal the RPIT. With the new solver we always normalize opaque types in the defining scope, so the recursive call ends up having a defining use of rpit<'temp> = &'unconstrained Foo. This use then results in an error for two reasons:

  • the arguments of the opaque type are not universal (i.e. free regions in the function)
  • it's impossible to know how 'unconstrained and 'temp are related in the general case, especially if the opaque has more than 1 region parameter

To support this I believe that we need to introduce the concept of a revealing use in the defining scope. The idea is that as long as there is one use of the opaque type with universal arguments, we use that defining use to fully infer the hidden type and then only check that the revealing uses are correct.

We currently compute mir_borrowck separately for closures and their parents. Given a closure with a signature fn(&'0 T) -> &'1 T borrowck of the closure itself does not know how '0 and '1 are related. It therefore propagates any constraints between these external regions to its parent, see the rustc-dev-guide. Using separate queries here is incompatible with this new design as we need to support revealing uses inside of closures while the defining use in the parent function. This is the case in the above example.


Instead of using a separate mir_borrowck query for nested bodies, I intend to borrowck nested bodies directly as part of mir_borrowck of the typeck root. I intend to keep the actual impls mostly separate for now, e.g. continue using a separate InferCtxt and nll region vars in each body.

We currently apply member constraints while computing the sccs of the region constraint graph in a single pass. This will need to support merging already computed sccs when checking revealing uses.

The exact modifications necessary to support revealing uses are still not totally clear to me and will require us to actually attempt to implement this design.

Mentors or Reviewers

@compiler-errors, @oli-obk

Process

The main points of the Major Change Process are as follows:

  • File an issue describing the proposal.
  • A types team member or contributor who is knowledgeable in the area can second by writing @rustbot second.
    • Finding a "second" suffices for internal changes. If however, you are proposing a new public-facing feature, such as a -C flag, then full team check-off is required.
    • Types team members can initiate a check-off via @rfcbot fcp merge on either the MCP or the PR.
  • Once an MCP is seconded, the Final Comment Period begins. If no objections are raised after 10 days, the MCP is considered approved.

You can read more about Major Change Proposals on forge.

Comments

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

@lcnr lcnr added the major-change A major change proposal label Jan 28, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jan 28, 2025

This issue is not meant to be used for technical discussion. There is a Zulip stream for that. Use this issue to leave procedural comments, such as volunteering to review, indicating that you second the proposal (or third, etc), or raising a concern that you would like to be addressed.

Concerns or objections to the proposal should be discussed on Zulip and formally registered here by adding a comment with the following syntax:

@rfcbot concern reason-for-concern 
<description of the concern> 

Concerns can be lifted with:

@rfcbot resolve reason-for-concern 

See documentation at https://forge.rust-lang.org

cc @rust-lang/types

@rustbot rustbot added the to-announce Announce this issue on triage meeting label Jan 28, 2025
@oli-obk
Copy link
Contributor

oli-obk commented Jan 29, 2025

@rustbot second

@rustbot rustbot added the final-comment-period The FCP has started, most (if not all) team members are in agreement label Jan 29, 2025
@lcnr
Copy link
Contributor Author

lcnr commented Feb 9, 2025

closing as accepted

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
final-comment-period The FCP has started, most (if not all) team members are in agreement major-change A major change proposal to-announce Announce this issue on triage meeting
Projects
None yet
Development

No branches or pull requests

3 participants