Rust的HRTB是相同的,但编译器表示一个类型比另一个更通用。

huangapple go评论64阅读模式
英文:

Rust HRTB is identical but compiler says one type is more general than the other

问题

以下是翻译好的部分:

编译器在编译此代码时报告了一个错误:

error[E0308]: mismatched types
  --> src/main.rs:14:5
   |
14 |     enter(x, identity);
   |     ^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected trait `for<'b> FnOnce(&'b i32,)`
              found trait `for<'a> FnOnce(&'a i32,)`
note: the lifetime requirement is introduced here
  --> src/main.rs:3:35
   |
3  |     F: for<'b> FnOnce(&'b i32) -> R,
   |                                   ^

我理解的是,trait 约束 for<'b> FnOnce(&'b i32) -> Ridentity 的签名 for<'a> fn(&'a i32) -> &'a i32 更一般,所以它应该通过。

然而,通用的 -> R 似乎是阻止编译的罪魁祸首,但我不知道为什么。

英文:

The following code is fully type annotated:

fn enter&lt;&#39;a, F, R&gt;(x: &amp;&#39;a i32, func: F) -&gt; R
where
    F: for&lt;&#39;b&gt; FnOnce(&amp;&#39;b i32) -&gt; R,
{
    func(x)
}

fn identity&lt;&#39;a&gt;(x: &amp;&#39;a i32) -&gt; &amp;&#39;a i32 {
    x
}

fn main() {
    let x = &amp;42;
    enter(x, identity);
}

The compiler reports an error when compiling it:

error[E0308]: mismatched types
  --&gt; src/main.rs:14:5
   |
14 |     enter(x, identity);
   |     ^^^^^^^^^^^^^^^^^^ one type is more general than the other
   |
   = note: expected trait `for&lt;&#39;b&gt; FnOnce&lt;(&amp;&#39;b i32,)&gt;`
              found trait `for&lt;&#39;a&gt; FnOnce&lt;(&amp;&#39;a i32,)&gt;`
note: the lifetime requirement is introduced here
  --&gt; src/main.rs:3:35
   |
3  |     F: for&lt;&#39;b&gt; FnOnce(&amp;&#39;b i32) -&gt; R,
   |                                   ^

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error

My understanding is that the trait bound for&lt;&#39;b&gt; FnOnce(&amp;&#39;b i32) -&gt; R is more general than identity's signature for&lt;&#39;a&gt; fn(&amp;&#39;a i32) -&gt; &amp;&#39;a i32, so it should pass.

However, the generic -&gt; R seems to be the culprit that stops the compilation but I don't know why.

I noticed there are similar questions, but they experienced the error because their types were not fully annotated and the compiler incorrectly inferred the type.

Related:

答案1

得分: 3

My understanding is that the trait bound for&lt;&#39;b&gt; FnOnce(&amp;&#39;b i32) -&gt; R is more general than identity's signature for&lt;&#39;a&gt; fn(&amp;&#39;a i32) -&gt; &amp;&#39;a i32, so it should pass.

我的理解是,特质约束 for&lt;&#39;b&gt; FnOnce(&amp;&#39;b i32) -&gt; Ridentity 的签名 for&lt;&#39;a&gt; fn(&amp;&#39;a i32) -&gt; &amp;&#39;a i32 更通用,所以它应该通过。

No it is not. When R is declared, &#39;b is not in the context, so it cannot depend on it (this is one way to view that, there are others).

不,不是这样的。当声明 R 时,&#39;b 不在上下文中,因此不能依赖它(这是一种看待方式,还有其他方式)。

This is necessary for APIs like std::thread::LocalKey::with() to be sound: if R was allowed to contain the lifetime (implicit in the case of with()), references to the thread local could escape the closure and with(), and then used on different threads, causing UB.

这对于像 std::thread::LocalKey::with() 这样的 API 来说是 必要的,如果允许 R 包含生命周期(在 with() 的情况下是隐式的),对线程本地的引用可能会逃逸闭包和 with(),然后在不同的线程上使用,导致未定义行为(UB)。

As far as I know, there is no way to have a generic return type and allow it to reference the parameters.

据我所知,目前没有办法使泛型返回类型并允许它引用参数。

英文:

> My understanding is that the trait bound for&lt;&#39;b&gt; FnOnce(&amp;&#39;b i32) -&gt; R is more general than identity's signature for&lt;&#39;a&gt; fn(&amp;&#39;a i32) -&gt; &amp;&#39;a i32, so it should pass.

No it is not. When R is declared, &#39;b is not in the context, so it cannot depend on it (this is one way to view that, there are others).

This is necessary for APIs like std::thread::LocalKey::with() to be sound: if R was allowed to contain the lifetime (implicit in the case of with()), references to the thread local could escape the closure and with(), and then used on different threads, causing UB.

As far as I know, there is no way to have a generic return type and allow it to reference the parameters.

huangapple
  • 本文由 发表于 2023年2月14日 03:08:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/75440244.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定