-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
slice of static lifetime elements, contains() requires operand to have static lifetime too #18214
Comments
This works: fn words<'a>() -> Vec<&'a str>
{
vec!["these","are","my","words"]
}
fn main() {
let my = "my".into_string();
if words().contains(&my.as_slice()) {
println!("Its in there!");
}
else {
println!("Word not found");
}
} I wonder if there is a way to make region inference figure this out itself. |
Yes using a non-specific lifetime like 'a makes the compiler happy. But it still seems like the lifetime checker isn't quite there. Vec defines contains() like impl<T: PartialEq> Vec<T> {
fn contains(&self, x: &T) -> bool;
} with no explicit lifetime references. The compiler is matching "&'static str" for "T" and therefore x must be a &'static str. But in reality, the vector must live "at least as long as" the parameter x... not the reverse, nor that the lifetimes are equal. But how do you express such a thing? It seems to me that lifetime annotation is either insufficient, or that (more likely) I still don't have a solid understanding of what lifetime annotation really means. |
And something is weird about the compiler penalizing you for supplying information more specific than it needs. |
Another datapoint: #[deriving(PartialEq, Show)]
struct Foo<T>(T);
fn hello() -> &'static str { "hello" }
fn foo() -> Foo<&'static str> { Foo(hello()) }
fn tup() -> (&'static str,) { (hello(),) }
fn main() {
let a = "hello".to_string();
// Works
assert_eq!(Foo(a.as_slice()), Foo(hello()));
// Works
assert_eq!((a.as_slice(),), tup());
// Fails to compile
//assert_eq!(Foo(a.as_slice()), foo());
} The fact that this works for a tuple but not a tuple struct makes it smell like a bug to me. cc @nikomatsakis |
I don't think that the initial example, at least, is a bug. @bkoropoff your example falls under the category of #3598 (infer of permit variance). I've been slowly moving a branch along fixing #3598 -- it's more-or-less functional now, so I should submit a refined RFC to try and land it. |
Hmm, well, the original example has since started working: http://is.gd/H2r3Hp This matches my intuition that when instantiating I guess the bug can be closed. |
Yeah it works now. Closing. |
Actually, now that I think about it a bit more, all of these examples would compile if the compiler permitted variance (and in fact the original example does compile on my branch). |
Oh, and I see the original compiles on master too :) Well, @bkoropoff's example still requires my branch, at least ;) I imagine the original example was fixed by the new type inference algorithm inserting more region variables. Might be worth looking into... |
…eykril fix: Comment out cast checks for unknown ptr kind Just like we don't check for types containing unknown. Fixes rust-lang#18214. See also https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Frust-analyzer/topic/Another.20case.20of.20.2318064.3F.
I'm not sure if this is a bug, or if it is already known, or if I'm just too dense to grok this stuff, but it seems to me that the lifetime of my needn't be any longer than the contains() call itself. Yet we have the lifetime error.
The text was updated successfully, but these errors were encountered: