Skip to content

generalize impl trait to permit multiple lifetime bounds#61775

Merged
bors merged 68 commits intorust-lang:masterfrom
nikomatsakis:issue-56238-multiple-lifetimes-async-fn-region-solver
Jul 3, 2019
Merged

generalize impl trait to permit multiple lifetime bounds#61775
bors merged 68 commits intorust-lang:masterfrom
nikomatsakis:issue-56238-multiple-lifetimes-async-fn-region-solver

Conversation

@nikomatsakis
Copy link
Contributor

@nikomatsakis nikomatsakis commented Jun 12, 2019

Generalizes the region solver to support "pick constraints". These have the form:

pick R0 from [R1..Rn]

where R1..Rn are called the "option regions". The idea is that R0 must be equal to some region in the set R1..Rn. These constraints are then used to handle cases like this:

fn foo<'a, 'b>(...) -> impl Trait<'a, 'b> { .. }

The problem here is that every region R in the hidden type must be equal to either 'a or 'b (or 'static) -- in the past, the only kinds of constraints we had were outlives constraints, and since 'a and 'b are unrelated, there was no outlives constraint we could issue that would enforce that (R: 'a and R: 'b are both too strict, for example). But now we can issue a pick constraint: pick R from ['a, 'b].

In general, solving pick constraints is tricky. We integrate them into the solver as follows. In general, during the propagation phase, we are monotonically growing a set of inference regions. To handle a case like pick R from [O...], where O... represents the option regions, we do the following:

  • Look for all the lower bounds of the region R -- that is, every region LB such that R: LB must hold.
  • Look for all the upper bounds of the region R -- that is, every region UB such that UB: R must hold.
  • Let the viable options be each option region O such that UB: O and O: LB for each UB, LB bound.
  • Find the minimal viable option M, where O: M holds for every option region O.

If there is such a minimal viable option, then we make R: M. (This may in turn influence other bits of inference.) If there is no minimal viable option, either because all options were eliminated or because none of the remaining options are minimal, we do nothing. Ultimately, if the pick constraint is not satisfied, an error is reported.

For this logic, we currently require that the option regions O are always lifetime parameters. To determine the bounds, we walk the various outlives edges that were otherwise introduced.

r? @matthewjasper
cc @cramertj

Fixes #56238

TODO:

  • Error messages include region variable info sometimes, how to fix?
  • Tests for bare existential type and other impl Trait usage

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-member-constraints `#[feature(member_constraints)]` 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. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

async fn should support multiple lifetimes

10 participants