Skip to content

Invalid error message about lifetimes when pattern matching with constants #18352

Closed
@netvl

Description

@netvl
Contributor

On the latest nightly (previously it worked fine) Rust fails to compile this code:

pub struct Namespace(pub HashMap<Option<String>, String>);

impl Namespace {
...
    pub fn is_essentially_empty(&self) -> bool {
        let Namespace(ref hm) = *self;
        for (k, v) in hm.iter() {
            match (k.as_ref().map(|k| k.as_slice()), v.as_slice()) {
                (None, NS_EMPTY_URI) |
                (Some(NS_XMLNS_PREFIX), NS_XMLNS_URI) |
                (Some(NS_XML_PREFIX), NS_XML_URI) => {},
                _ => return false
            }
        }
        true
    }
...
}

It emits this error message:

   Compiling rust-xml v0.1.0 (file:///home/dpx-infinity/dev/lang/rust/projects/rust-xml)
src/namespace.rs:41:23: 41:29 error: cannot infer an appropriate lifetime for pattern due to conflicting requirements
src/namespace.rs:41         let Namespace(ref hm) = *self;
                                          ^~~~~~
src/namespace.rs:43:54: 43:55 note: first, the lifetime cannot outlive the expression at 43:53...
src/namespace.rs:43             match (k.as_ref().map(|k| k.as_slice()), v.as_slice()) {
                                                                         ^
src/namespace.rs:43:54: 43:55 note: ...so that pointer is not dereferenced outside its lifetime
src/namespace.rs:43             match (k.as_ref().map(|k| k.as_slice()), v.as_slice()) {
                                                                         ^
src/namespace.rs:42:23: 42:25 note: but, the lifetime must be valid for the expression at 42:22...
src/namespace.rs:42         for (k, v) in hm.iter() {
                                          ^~
src/namespace.rs:42:23: 42:25 note: ...so that pointer is not dereferenced outside its lifetime
src/namespace.rs:42         for (k, v) in hm.iter() {
                                          ^~

I managed to strip it down to this example:

const X: &'static str = "12345";

pub fn test(s: String) -> bool {
    match s.as_slice() {
        X => true,
        _ => false
    }
}

It fails to compile with this error:

/tmp/rs/lifetimes/src/lib.rs:18:11: 18:12 error: `s` does not live long enough
/tmp/rs/lifetimes/src/lib.rs:18     match s.as_slice() {
                                          ^
note: reference must be valid for the static lifetime...
/tmp/rs/lifetimes/src/lib.rs:17:32: 22:2 note: ...but borrowed value is only valid for the block at 17:31
/tmp/rs/lifetimes/src/lib.rs:17 pub fn test(s: String) -> bool {
/tmp/rs/lifetimes/src/lib.rs:18     match s.as_slice() {
/tmp/rs/lifetimes/src/lib.rs:19         X => true,
/tmp/rs/lifetimes/src/lib.rs:20         _ => false
/tmp/rs/lifetimes/src/lib.rs:21     }
/tmp/rs/lifetimes/src/lib.rs:22 }

If X => is replaced with "12345" =>, then it compiles fine, so the error seems to be related to matching on consts.

Activity

ghost
self-assigned this
on Oct 26, 2014
ghost

ghost commented on Oct 26, 2014

@ghost

@netvl Sorry for the breakage, fix on its way.

added a commit that references this issue on Oct 22, 2024

Auto merge of rust-lang#18354 - roife:safe-kw-2, r=lnicola

f21a01f
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Participants

      @netvl

      Issue actions

        Invalid error message about lifetimes when pattern matching with constants · Issue #18352 · rust-lang/rust