Skip to content

Borrow checker incorrectly accepts code when calling function with complex lifetime bounds through a fn pointer #57170

Closed
@ennis

Description

@ennis

The following code compiles and prints a bogus value:

fn shorten_lifetime<'a, 'b, 'min>(a: &'a i32, b: &'b i32) -> &'min i32
where 'a: 'min, 'b: 'min
{
    if *a < *b {
        &a
    } else {
        &b
    }
}


fn main()
{
    let fnptr = &shorten_lifetime;
    
    let a = &5;
    let ptr = {
        let b = 3;
        let b = &b;
        //let c = shorten_lifetime(a, b);
        let c = fnptr(a, b);
        c
    };
    
    println!("ptr = {:?}", ptr);
    
}

Output (release mode):

ptr = -1876488848

(playground: https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=048d856b4689599b1e35f0a44ebe629f)

Expected result: a borrow checker error, the same as the one obtained when calling shorten_lifetime directly.

I accidentally ran into this issue when trying to spell the fn pointer type of fnptr (I'm not sure how to add constraints to the lifetimes of a higher-ranked fn type like for<'a, 'b> fn(...) -> T)

Metadata

Metadata

Assignees

Labels

A-NLLArea: Non-lexical lifetimes (NLL)I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessNLL-soundWorking towards the "invalid code does not compile" goalP-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-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