Skip to content

Compile fail with implicit return #94980

@marcbowes

Description

@marcbowes

I tried this code:

use std::sync::{Arc, Mutex, Weak};

fn main() {
    let value = Arc::new(Mutex::new(String::new()));
    let weak = Arc::downgrade(&value);
    let _ = foo(weak);
}

fn foo(weak: Weak<Mutex<String>>) -> usize {
    let upgraded = weak.upgrade().unwrap();
    match upgraded.try_lock() {
        Ok(guard) => guard,
        _ => unreachable!(),
    }
    .len()
}

I expected to see this happen: it compiles!

Instead, this happened:

error[E0597]: `upgraded` does not live long enough
  --> src/main.rs:11:11
   |
11 |     match upgraded.try_lock() {
   |           ^^^^^^^^^^^^^^^^^^^
   |           |
   |           borrowed value does not live long enough
   |           a temporary with access to the borrow is created here ...
...
16 | }
   | -
   | |
   | `upgraded` dropped here while still borrowed
   | ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `Result<MutexGuard<'_, String>, TryLockError<MutexGuard<'_, String>>>`
   |
   = note: the temporary is part of an expression at the end of a block;
           consider forcing this temporary to be dropped sooner, before the block's local variables are dropped
help: for example, you could save the expression's value in a new local variable `x` and then make `x` be the expression at the end of the block
   |
11 ~     let x = match upgraded.try_lock() {
12 |         Ok(guard) => guard,
13 |         _ => unreachable!(),
14 |     }
15 ~     .len(); x
   |

For more information about this error, try `rustc --explain E0597`.
error: could not compile `explret` due to previous err

What's weird is changing to an explicit return fixes the problem:

fn foo(weak: Weak<Mutex<String>>) -> usize {
    let upgraded = weak.upgrade().unwrap();
    return match upgraded.try_lock() {
        Ok(guard) => guard,
        _ => unreachable!(),
    }
    .len();
}

Meta

rustc --version --verbose:

rustc 1.59.0 (9d1b2106e 2022-02-23)
binary: rustc
commit-hash: 9d1b2106e23b1abd32fce1f17267604a5102f57a
commit-date: 2022-02-23
host: x86_64-apple-darwin
release: 1.59.0
LLVM version: 13.0.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-borrow-checkerArea: The borrow checkerC-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions