I am not good at English. Sorry if there are any funny expressions. Additionally, the title of this topic may not be appropriate, as I am just guessing this is probably relevant.
Anyway, please see the code below.
In this code, I don't understand why there are no compilation errors with test3. It seems to me that the problematic part of test2 has not been fixed.
What is going on in test3?
fn main() {}
trait SomeTrait {
fn method(&self) {}
}
impl<T: 'static + Sized> SomeTrait for T {
// NOP.
}
// ✅ No Compile error, and I can understand this👌.
fn test1<T: 'static + ?Sized>(arg: &'static Box<T>) {
arg.as_ref().method();
}
/* ❌ Compile error, but I can understand this👌.
The error says "error[E0521]: borrowed data escapes outside of function".
Maybe the value obtained by traversing `arg` does not satisfy the `static`
boundary required from blanket implementation. */
fn test2<T: 'static + ?Sized>(arg: &Box<T>) {
arg.as_ref().method();
}
/* ✅ No Compile error, but I can't understand this💦.
The only difference with `test2` is the difference between `?Sized` or `Sized`,
and I don't think it resolves what the error was pointed in `test2`. */
fn test3<T: 'static + Sized>(arg: &Box<T>) {
arg.as_ref().method();
}
I think what's happening here is that after .as_ref() you get an &T. When you call method the compiler tries to first check if T: SomeTrait, but it fails because T: ?Sized, and the impl for SomeTrait requires T: Sized. So it falls back to calling .method() on the reference itself, i.e. it tries to check if &T: SomeTrait, but this fails because the implementation requires 'static and the reference has a non-'static lifetime. Hence the error about the borrowed data not living long enough.
No, there's only one .as_ref()[1], but there are multiple ways to call .method(). One tries to consider T the type that should implement SomeTrait (but it fails because a trait bound is missing, thus it leads to the next one) and the other tries to consider &T the type that should implement SomeTrait (which fails too, but with a lifetime error, and this is where the compiler stops)
well, technically there are multiple ways to call .as_ref() too, but the first one succeed so the others are not considered. It also wouldn't change anything for your error. ↩︎
Normally, the previous explanation would have been enough... However, I carelessly forgot something very basic (&self with dot operator can accept non-referential types). I’m embarrassed.