Discussion:
[rust-dev] Bug in lifetime inference?
Kai Noda
2014-08-30 08:52:00 UTC
Permalink
Hi Rusters,

I'm very new to Rust, so I'd like you to check if this is really a compiler
bug or not.

fn main() {
let s1 = &[0i];
{
let s2 = &[0i];
let s3 = if true { s1 } else { s2 };
};
}

http://is.gd/NCeGpl

<anon>:5:19: 5:23 error: borrowed value does not live long enough
<anon>:5 let s2 = &[0i];
^~~~
<anon>:2:11: 8:2 note: reference must be valid for the block at 2:10...
<anon>:2 fn main() {
<anon>:3 let s1 = &[0i];
<anon>:4 {
<anon>:5 let s2 = &[0i];
<anon>:6 let s3 = if true { s1 } else { s2 };
<anon>:7 };
...
<anon>:4:5: 7:6 note: ...but borrowed value is only valid for the block at 4:4
<anon>:4 {
<anon>:5 let s2 = &[0i];
<anon>:6 let s3 = if true { s1 } else { s2 };
<anon>:7 };
error: aborting due to previous error


Seems like s1 and s2 are inferred as &[int, ..1] and when I manually type
them as &[int], it successfully compiles.

fn main() {
let s1: &[int] = &[0i];
{
let s2: &[int] = &[0i];
let s3 = if true { s1 } else { s2 };
};
}

Putting s1 and s2 into a single block also satisfies the compiler.

fn main() {
let s1 = &[0i];

let s2 = &[0i];
let s3 = if true { s1 } else { s2 };
}

I came from C++ and I think the way I take reference of a fixed vector
literal is correct.
http://doc.rust-lang.org/rust.html#pointer-types

I was originally trying to fix this line which doesn't compile with the
nightly build of Rust:
https://github.com/servo/rust-url/blob/master/src/form_urlencoded.rs#L55

No similar issue is filed here:
https://github.com/rust-lang/rust/labels/A-lifetimes

Best regards,
Kai

?? ? <nodakai at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140830/f2445fa2/attachment.html>
David Brown
2014-09-10 00:22:13 UTC
Permalink
I've seen something similar recently, with this code:

----------------------------------------------------------------------
fn main() {
// Fails.
assert_eq!(stuff(), &[]);

// Works
let tmp: &'static [uint] = &[];
assert_eq!(stuff(), tmp);
}

static simple: &'static [uint] = &[1, 2];

fn stuff() -> &'static [uint] {
simple
}
----------------------------------------------------------------------

The failing code worked a week or so ago. Similar issue in that I can
make it work by giving an explicit type for the literal array.

David
Post by Kai Noda
Hi Rusters,
I'm very new to Rust, so I'd like you to check if this is really a
compiler bug or not.
fn main() {
? ? let s1 = &[0i];
? ? {
? ? ? ? let s2 = &[0i];
? ? ? ? let s3 = if true { s1 } else { s2 };
? ? };
}
[1]http://is.gd/NCeGpl
<anon>:5:19: 5:23 error: borrowed value does not live long enough
<anon>:5 let s2 = &[0i];
^~~~
<anon>:2:11: 8:2 note: reference must be valid for the block at 2:10...
<anon>:2 fn main() {
<anon>:3 let s1 = &[0i];
<anon>:4 {
<anon>:5 let s2 = &[0i];
<anon>:6 let s3 = if true { s1 } else { s2 };
<anon>:7 };
...
<anon>:4:5: 7:6 note: ...but borrowed value is only valid for the block at 4:4
<anon>:4 {
<anon>:5 let s2 = &[0i];
<anon>:6 let s3 = if true { s1 } else { s2 };
<anon>:7 };
error: aborting due to previous error
Seems like s1 and s2 are inferred as &[int, ..1] and when I manually
type them as &[int], it successfully compiles.
fn main() {
? ? let s1: &[int] = &[0i];
? ? {
? ? ? ? let s2: &[int] = &[0i];
? ? ? ? let s3 = if true { s1 } else { s2 };
? ? };
}
Putting s1 and s2 into a single block also satisfies the compiler.
fn main() {
? ? let s1 = &[0i];
? ? let s2 = &[0i];
? ? let s3 = if true { s1 } else { s2 };
}
I came from C++ and I think the way I take reference of a fixed vector
literal is correct.
[2]http://doc.rust-lang.org/rust.html#pointer-types
I was originally trying to fix this line which doesn't compile with
[3]https://github.com/servo/rust-url/blob/master/src/form_urlencoded.rs#L55
[4]https://github.com/rust-lang/rust/labels/A-lifetimes
Best regards,
Kai
??? ? <[5]nodakai at gmail.com>
References
Visible links
1. http://is.gd/NCeGpl
2. http://doc.rust-lang.org/rust.html#pointer-types
3. https://github.com/servo/rust-url/blob/master/src/form_urlencoded.rs#L55
4. https://github.com/rust-lang/rust/labels/A-lifetimes
5. mailto:nodakai at gmail.com
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
Kai Noda
2014-09-10 10:26:47 UTC
Permalink
Hi David,

I stopped worrying about the alleged bug I had reported after I saw Git
HEAD happily compiled it a few days later.

I found your case more interesting because I could compile your code by
changing

assert_eq!(stuff(), &[]);

to

let b = stuff() == &[];

Regards,
Kai
Post by David Brown
----------------------------------------------------------------------
fn main() {
// Fails.
assert_eq!(stuff(), &[]);
// Works
let tmp: &'static [uint] = &[];
assert_eq!(stuff(), tmp);
}
static simple: &'static [uint] = &[1, 2];
fn stuff() -> &'static [uint] {
simple
}
----------------------------------------------------------------------
The failing code worked a week or so ago. Similar issue in that I can
make it work by giving an explicit type for the literal array.
David
Post by Kai Noda
Hi Rusters,
I'm very new to Rust, so I'd like you to check if this is really a
compiler bug or not.
fn main() {
let s1 = &[0i];
{
let s2 = &[0i];
let s3 = if true { s1 } else { s2 };
};
}
[1]http://is.gd/NCeGpl
<anon>:5:19: 5:23 error: borrowed value does not live long enough
<anon>:5 let s2 = &[0i];
^~~~
<anon>:2:11: 8:2 note: reference must be valid for the block at 2:10...
<anon>:2 fn main() {
<anon>:3 let s1 = &[0i];
<anon>:4 {
<anon>:5 let s2 = &[0i];
<anon>:6 let s3 = if true { s1 } else { s2 };
<anon>:7 };
...
<anon>:4:5: 7:6 note: ...but borrowed value is only valid for the block at 4:4
<anon>:4 {
<anon>:5 let s2 = &[0i];
<anon>:6 let s3 = if true { s1 } else { s2 };
<anon>:7 };
error: aborting due to previous error
Seems like s1 and s2 are inferred as &[int, ..1] and when I manually
type them as &[int], it successfully compiles.
fn main() {
let s1: &[int] = &[0i];
{
let s2: &[int] = &[0i];
let s3 = if true { s1 } else { s2 };
};
}
Putting s1 and s2 into a single block also satisfies the compiler.
fn main() {
let s1 = &[0i];
let s2 = &[0i];
let s3 = if true { s1 } else { s2 };
}
I came from C++ and I think the way I take reference of a fixed vector
literal is correct.
[2]http://doc.rust-lang.org/rust.html#pointer-types
I was originally trying to fix this line which doesn't compile with
[3]https://github.com/servo/rust-url/blob/master/src/form_
urlencoded.rs#L55
[4]https://github.com/rust-lang/rust/labels/A-lifetimes
Best regards,
Kai
?? ? <[5]nodakai at gmail.com>
References
Visible links
1. http://is.gd/NCeGpl
2. http://doc.rust-lang.org/rust.html#pointer-types
3. https://github.com/servo/rust-url/blob/master/src/form_
urlencoded.rs#L55
4. https://github.com/rust-lang/rust/labels/A-lifetimes
5. mailto:nodakai at gmail.com
_______________________________________________
Post by Kai Noda
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20140910/154c4f45/attachment.html>
David Brown
2014-09-10 15:20:25 UTC
Permalink
Post by Kai Noda
Hi David,
I stopped worrying about the alleged bug I had reported after I saw
Git HEAD happily compiled it a few days later.
I found your case more interesting because I could compile your code
by changing
assert_eq!(stuff(), &[]);
to
let b = stuff() == &[];
`assert_eq` does the equality check in both directions. It seems
that:

let b = &[] == stuff();

still fails to compile:
test.rs:6:20: 6:27 error: mismatched types: expected `&[<generic #11>, .. 0]`, found `&'static [uint]` (expected vector, found vector)
test.rs:6 let b = &[] == stuff();
^~~~~~~
test.rs:6:13: 6:27 error: cannot determine a type for this bounded type parameter: unconstrained type
test.rs:6 let b = &[] == stuff();

which is basically the same error seen in the expansion of the
`assert_eq`.

It seems that the array literal cannot be used on the left side of a
comparison.

If anything, the "expected vector, found vector" isn't particularly
helpful.

David
Post by Kai Noda
Regards,
Kai
----------------------------------------------------------------------
fn main() {
? ?// Fails.
? ?assert_eq!(stuff(), &[]);
? ?// Works
? ?let tmp: &'static [uint] = &[];
? ?assert_eq!(stuff(), tmp);
}
static simple: &'static [uint] = &[1, 2];
fn stuff() -> &'static [uint] {
? ?simple
}
----------------------------------------------------------------------
The failing code worked a week or so ago.? Similar issue in that I
can
make it work by giving an explicit type for the literal array.
David
Hi Rusters,
I'm very new to Rust, so I'd like you to check if this is really a
compiler bug or not.
fn main() {
? ? let s1 = &[0i];
? ? {
? ? ? ? let s2 = &[0i];
? ? ? ? let s3 = if true { s1 } else { s2 };
? ? };
}
[1][2]http://is.gd/NCeGpl
<anon>:5:19: 5:23 error: borrowed value does not live long enough
<anon>:5? ? ? ? ?let s2 = &[0i];
? ? ? ? ? ? ? ? ? ? ? ? ? ^~~~
<anon>:2:11: 8:2 note: reference must be valid for the block at 2:10...
<anon>:2 fn main() {
<anon>:3? ? ?let s1 = &[0i];
<anon>:4? ? ?{
<anon>:5? ? ? ? ?let s2 = &[0i];
<anon>:6? ? ? ? ?let s3 = if true { s1 } else { s2 };
<anon>:7? ? ?};
? ? ? ? ...
<anon>:4:5: 7:6 note: ...but borrowed value is only valid for the block at 4:4
<anon>:4? ? ?{
<anon>:5? ? ? ? ?let s2 = &[0i];
<anon>:6? ? ? ? ?let s3 = if true { s1 } else { s2 };
<anon>:7? ? ?};
error: aborting due to previous error
Seems like s1 and s2 are inferred as &[int, ..1] and when I
manually
type them as &[int], it successfully compiles.
fn main() {
? ? let s1: &[int] = &[0i];
? ? {
? ? ? ? let s2: &[int] = &[0i];
? ? ? ? let s3 = if true { s1 } else { s2 };
? ? };
}
Putting s1 and s2 into a single block also satisfies the compiler.
fn main() {
? ? let s1 = &[0i];
? ? let s2 = &[0i];
? ? let s3 = if true { s1 } else { s2 };
}
I came from C++ and I think the way I take reference of a fixed vector
literal is correct.
[2][3]http://doc.rust-lang.org/rust.html#pointer-types
I was originally trying to fix this line which doesn't compile with
[3][4]https://github.com/servo/rust-url/blob/master/src/form_urlencoded.rs#L55
[4][5]https://github.com/rust-lang/rust/labels/A-lifetimes
Best regards,
Kai
??? ? <[5][6]nodakai at gmail.com>
References
? Visible links
? 1. [7]http://is.gd/NCeGpl
? 2. [8]http://doc.rust-lang.org/rust.html#pointer-types
? 3.
[9]https://github.com/servo/rust-url/blob/master/src/form_urlencoded.rs#L55
? 4. [10]https://github.com/rust-lang/rust/labels/A-lifetimes
? 5. mailto:[11]nodakai at gmail.com
_______________________________________________
Rust-dev mailing list
[12]Rust-dev at mozilla.org
[13]https://mail.mozilla.org/listinfo/rust-dev
References
Visible links
1. mailto:davidb at davidb.org
2. http://is.gd/NCeGpl
3. http://doc.rust-lang.org/rust.html#pointer-types
4. https://github.com/servo/rust-url/blob/master/src/form_urlencoded.rs#L55
5. https://github.com/rust-lang/rust/labels/A-lifetimes
6. mailto:nodakai at gmail.com
7. http://is.gd/NCeGpl
8. http://doc.rust-lang.org/rust.html#pointer-types
9. https://github.com/servo/rust-url/blob/master/src/form_urlencoded.rs#L55
10. https://github.com/rust-lang/rust/labels/A-lifetimes
11. mailto:nodakai at gmail.com
12. mailto:Rust-dev at mozilla.org
13. https://mail.mozilla.org/listinfo/rust-dev
Loading...