Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
netvl opened this issue Oct 26, 2014 · 1 comment · Fixed by #18356
Closed

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

netvl opened this issue Oct 26, 2014 · 1 comment · Fixed by #18356

Comments

@netvl
Copy link
Contributor

netvl commented Oct 26, 2014

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.

netvl added a commit to netvl/xml-rs that referenced this issue Oct 26, 2014
@ghost ghost self-assigned this Oct 26, 2014
@ghost
Copy link

ghost commented Oct 26, 2014

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant