Skip to content

pin!() changed temporary lifetime extension behavior in version 1.88.0 with edition 2024 tail expression temporary scopes #145784

@theemathas

Description

@theemathas

I tried this code (edition 2024):

#![allow(unused_braces)]

use std::pin::{Pin, pin};

struct HasDrop;

impl Drop for HasDrop {
    fn drop(&mut self) {
        println!("drop");
    }
}

fn main() {
    foo(pin!({ &HasDrop as *const HasDrop }));
}

fn foo(_: Pin<&mut *const HasDrop>) {
    println!("foo");
}

In version 1.87.0, the code printed drop then foo. In version 1.88.0, the code printed foo then drop.

Since version 1.88.0, the macro expands to super let mut pinned = { &HasDrop };, which extends the lifetime of HasDrop to be as long as pinned. (Thanks to @dianne for figuring this out.)

The reason for the different behavior in version 1.87.0 is presumably due to the edition 2024 temporary scope change.

This issue won't be fixed by #145342, since this issue doesn't involve if let.

Presumably regressed in #139114 cc @m-ou-se

@rustbot labels +regression-from-stable-to-stable +A-pin +F-super_let

Meta

Reproducible on godbolt, with --edition=2024.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-pinArea: PinA-temporary-lifetime-extensionArea: temporary lifetime extensionC-bugCategory: This is a bug.F-super_letit's super, let's go!I-libs-api-nominatedNominated for discussion during a libs-api team meeting.I-prioritizeIssue: Indicates that prioritization has been requested for this issue.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-langRelevant to the language teamregression-from-stable-to-stablePerformance or correctness regression from one stable version to another.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions