Skip to content

confusing lifetime inference #33529

Open
Open
@BusyJay

Description

@BusyJay

Consider following snippet:

use std::error::Error;

use std::io::{self, ErrorKind};

fn caused_of<'a>(mut err: &'a (Error + 'static)) -> Option<&'a io::Error> {
    loop {
        match err.downcast_ref::<io::Error>() {
            None => match err.cause() {
                None => return None,
                Some(cause) => err = cause,
            },
            d => return d,
        }
    }
}

fn main() {
    let e = io::Error::new(ErrorKind::Other, "oh no!");
    println!("{:?}", caused_of(&e));
}

According to Book, cause's lifetime should be err's lifetime. which is 'a, so it should be safe to assign cause to err directly. But I got following warnnings:

test.rs:8:34: 8:39 error: cannot infer an appropriate lifetime for autoref due to conflicting requirements [E0495]
test.rs:8                       None => match err.cause() {
                                           ^~~~~
test.rs:8:30: 8:41 note: first, the lifetime cannot outlive the method call at 8:29...
test.rs:8                       None => match err.cause() {
                                       ^~~~~~~~~~~
test.rs:8:30: 8:33 note: ...so that method receiver is valid for the method call
test.rs:8                       None => match err.cause() {
                                       ^~~
test.rs:5:75: 15:25 note: but, the lifetime must be valid for the lifetime 'a as defined on the block at 5:74...
test.rs:5 fn caused_of<'a>(mut err: &'a (Error + 'static)) -> Option<&'a io::Error> {
                                                                                    ^
test.rs:10:48: 10:53 note: ...so that trait type parameters matches those specified on the impl (expected std::ops::CoerceUnsized<&'a std::error::Error + 'static>, found std::ops::CoerceUnsized<&std::error::Error + 'static>)
test.rs:10                                                      Some(cause) => err = cause,
                                                          ^~~~~
error: aborting due to previous error

Am I missing something here?

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-lifetimesArea: Lifetimes / regionsA-type-systemArea: Type systemC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.T-typesRelevant to the types 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