-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Borrow checker bug: cannot return reference to temporary value
#66541
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
Comments
The other 3 examples not compiling is not surprising, they contain runtime code, so any reference to it will return a reference to a local variable. I think the suprising thing to folks is that the first example compiles. I have no idea how to improve diagnostics to the point where this difference becomes clear unless we introduce |
@oli-obk https://doc.rust-lang.org/reference/expressions.html#temporary-lifetimes this chapter in reference may help for an explanation? |
Yes, thanks for this doc links, something become more clear, but it is still not obvious with this case: ....
Baz { foo: Test::foo() }
..... |
Why this not compiles? const fn foo() -> &'static str {
"Hello, World!"
}
fn test() -> &'static [&'static str] {
&[
"Line 1",
foo(),
]
} |
Before getting into that, note that const fn foo() -> &'static str {
"Hello, World!"
}
const FOO: &'static str = foo();
fn test() -> &'static [&'static str] {
&[
"Line 1",
FOO,
]
} does in fact compile. The underlying reason is that |
Ok. I still has a question. Is this how the compiler intended to work by RFC or it is just current limitations of implementation (meaning unable to use a result of a const function for static slice)? And one more, is this issue has something what may be considered as an issue or should I just close it, since everyone agreed that it is "working as expected"? |
This is not a limitation of the implementation. While the original promoted locals RFC suggested to allow const fn calls, it has since been discovered that doing so poses forward compatibility problems that we'd rather avoid. Since you can always insert an intermediate constant, this seems easily worked around. What we would like to see is a |
I had this simplest example for this "bug". Now I understand why it is intended. It would be nice to have trait AsStr {
fn as_str(&self) -> &str;
}
impl AsStr for &[u8] {
fn as_str(&self) -> &str {
unsafe { str::from_utf8_unchecked(self) }
}
}
fn foo(buf: &[u8]) -> &str {
unsafe { str::from_utf8_unchecked(buf) }
}
// Error: cannot return value referencing temporary value
fn bar(buf: &[u8]) -> &str {
return buf.borrow().as_str();
}
// Okay
fn baz(buf: &[u8]) -> &str {
return foo(buf);
}
// Error: cannot return value referencing function parameter `buf`
fn qux(buf: &[u8]) -> &str {
return AsStr::as_str(&buf);
} |
@qiujiangkun I don't think your example relates to this issue. You are just getting a borrow check error. The examples here are actually fully constant and don't rely on arguments. |
Hi, here is an example of very strange error I have stuck with:
and the error message:
The text was updated successfully, but these errors were encountered: