rust icon indicating copy to clipboard operation
rust copied to clipboard

Propagate temporary lifetime extension into if and match.

Open m-ou-se opened this issue 1 year ago • 6 comments

This PR makes this work:

let a = if true {
    ..;
    &temp() // used to error, but now gets lifetime extended
} else {
    ..;
    &temp() // used to error, but now gets lifetime extended
};

and

let a = match () {
    _ => {
        ..;
        &temp() // used to error, but now gets lifetime extended
    }
};

to make it consistent with:

let a = {
    ..;
    &temp() // lifetime is extended
};

This is one small part of the temporary lifetimes work.

This part is backwards compatible (so doesn't need be edition-gated), because all code affected by this change previously resulted in a hard error.

m-ou-se avatar Feb 20 '24 14:02 m-ou-se

cc @nikomatsakis @dingxiangfei2009 see https://rust-lang.zulipchat.com/#narrow/stream/403629-t-lang.2Ftemporary-lifetimes-2024/topic/Separate.20the.20part.20on.20if.20bodies.20and.20match.20arms.3F/near/422433608

m-ou-se avatar Feb 20 '24 14:02 m-ou-se

Based on discussion in the @rust-lang/lang meeting today:

@rfcbot merge

joshtriplett avatar Feb 21 '24 17:02 joshtriplett

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

  • [x] @joshtriplett
  • [x] @nikomatsakis
  • [x] @pnkfelix
  • [x] @scottmcm
  • [x] @tmandry

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns. See this document for info about what commands tagged team members can give me.

rfcbot avatar Feb 21 '24 17:02 rfcbot

@rfcbot reviewed

I thought at first there were backwards compatibility concerns here. But as I dug in, I realized that there isn't. Looking at this example that Mara gave:

fn main() {
    drop(if true {
        ..;
        &temp(0) // used to error, but now gets lifetime extended
    } else {
        ..;
        &temp(1) // used to error, but now gets lifetime extended
    });
}

This winds up being a guaranteed error because, when we enter into an if expression, we always free the temporaries created within on exiting from the if. I remember making this change -- the idea was that wherever we have control flow divergence we will drop temporaries before we come back together -- and I believe the reason was because of the limitations of codegeneration way back then (long before we had MIR, for example). This makes sense because to support this pattern you need dynamic drop -- i.e., there is a temporary slot that will store temp(0) but it's only created conditionally -- and we didn't have that at the time. So I think it seemed obvious that we needed this restriction, but we don't anymore.

(Same for match etc)

nikomatsakis avatar Feb 29 '24 14:02 nikomatsakis

:bell: This is now entering its final comment period, as per the review above. :bell:

rfcbot avatar Feb 29 '24 14:02 rfcbot

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

rfcbot avatar Mar 10 '24 14:03 rfcbot

r? compiler

m-ou-se avatar Mar 20 '24 09:03 m-ou-se

cool r? @compiler-errors idk

BoxyUwU avatar Apr 03 '24 22:04 BoxyUwU

@bors r+

compiler-errors avatar Apr 09 '24 15:04 compiler-errors

:pushpin: Commit f4caa832dad4482ec1fa85bdbc3156c83cc948de has been approved by compiler-errors

It is now in the queue for this repository.

bors avatar Apr 09 '24 15:04 bors

:hourglass: Testing commit f4caa832dad4482ec1fa85bdbc3156c83cc948de with merge dd71663ba9a39b5f970d310343a3714e632b98ce...

bors avatar Apr 10 '24 09:04 bors

The job x86_64-gnu-aux failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

rust-log-analyzer avatar Apr 10 '24 11:04 rust-log-analyzer

:broken_heart: Test failed - checks-actions

bors avatar Apr 10 '24 11:04 bors

@bors retry

compiler-errors avatar Apr 10 '24 14:04 compiler-errors

:hourglass: Testing commit f4caa832dad4482ec1fa85bdbc3156c83cc948de with merge b3bd7058c139e71bae0862ef8f8ac936208873e9...

bors avatar Apr 10 '24 18:04 bors

:sunny: Test successful - checks-actions Approved by: compiler-errors Pushing b3bd7058c139e71bae0862ef8f8ac936208873e9 to master...

bors avatar Apr 10 '24 20:04 bors

Finished benchmarking commit (b3bd7058c139e71bae0862ef8f8ac936208873e9): comparison URL.

Overall result: no relevant changes - no action needed

@rustbot label: -perf-regression

Instruction count

This benchmark run did not return any relevant results for this metric.

Max RSS (memory usage)

Results

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
-5.1% [-5.1%, -5.1%] 1
All ❌✅ (primary) - - 0

Cycles

This benchmark run did not return any relevant results for this metric.

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 675.28s -> 675.727s (0.07%) Artifact size: 318.45 MiB -> 318.44 MiB (-0.00%)

rust-timer avatar Apr 10 '24 22:04 rust-timer

This looks to be the likely cause of a regression in temporary lifetime extension in constant initializers.

CAD97 avatar Jun 16 '24 19:06 CAD97

Although looking at the actual change, it doesn't quite make sense how this would be responsible when the other expr kinds don't "cover" the temporary lifetime the way that's being seen in #126562. So I guess there must be a different location where const promotion is handled that also needs to be taught to peek through if and match expression kinds.

CAD97 avatar Jun 16 '24 19:06 CAD97

Only candidate I saw with a quick scan was:

https://github.com/rust-lang/rust/blob/55cac26a9ef17da1c9c77c0816e88e178b7cc5dd/compiler/rustc_hir_typeck/src/rvalue_scopes.rs#L26-L52

but that's looking at ET not E& and I'm really not sure on the exact relation between the two

CAD97 avatar Jun 16 '24 19:06 CAD97

(see issue for further information; it looks like this may have gotten fingered incorrectly)

CAD97 avatar Jun 16 '24 20:06 CAD97