英文:
Why does the error "is not constrained by the impl trait" occur when only changing the definition of the offending type parameter?
问题
这个问题是基于之前的问题构建的,可能对理解上下文有所帮助。
以下是问题中的原始特质以及最简单的实现(即对于 T: Fn() -> TR
):
pub trait Ext<T> {
type Output;
fn call_with_tuple(self, x: T) -> Self::Output;
fn to_tuple_fn(self) -> Box<dyn Fn(T) -> Self::Output>;
}
impl<T: 'static, TR> Ext<()> for T
where
T: Fn() -> TR,
{
type Output = TR;
fn call_with_tuple(self, _: ()) -> Self::Output {
self()
}
fn to_tuple_fn(self) -> Box<dyn Fn(()) -> Self::Output> {
Box::new(move |_| self())
}
}
为了解决从泛型函数返回值后丢失了一些类型信息的问题(特别是 to_tuple_fn
不会保留原始值的任何特质,比如 Clone
),我们可以尝试将 T: Fn() -> TR
更改为 T: CloneableFn<(), TR>
。这会导致错误:
error[E0207]: the type parameter `TR` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:52:18
|
52 | impl<T: 'static, TR> Ext<()> for T
| ^^ unconstrained type parameter
但我不明白为什么会出现这种情况,因为只有 TR
的定义发生了变化,而在特质实现的其余部分中它并未改变。
这里是演示此问题的示例链接。
英文:
This question builds on a previous question, which may be useful to see for context.
Here is the original trait in question, along with the simplest implementation (i.e. for T: Fn() -> TR
):
pub trait Ext<T> {
type Output;
fn call_with_tuple(self, x: T) -> Self::Output;
fn to_tuple_fn(self) -> Box<dyn Fn(T) -> Self::Output>;
}
impl<T: 'static, TR> Ext<()> for T
where
T: Fn() -> TR,
{
type Output = TR;
fn call_with_tuple(self, _: ()) -> Self::Output {
self()
}
fn to_tuple_fn(self) -> Box<dyn Fn(()) -> Self::Output> {
Box::new(move |_| self())
}
}
To get around the issue where some type information is lost after a value is returned from a generic function (in particular to_tuple_fn
will not preserve any traits of the original value, such as Clone
), we can try to change T: Fn() -> TR
to be T: CloneableFn<(), TR>
. This results in the error:
error[E0207]: the type parameter `TR` is not constrained by the impl trait, self type, or predicates
--> src/main.rs:52:18
|
52 | impl<T: 'static, TR> Ext<()> for T
| ^^ unconstrained type parameter
But I don't see why this is the case, as only the definition of TR
change, not how it appears in the rest of the trait impl.
Here's a playground link demonstrating the issue.
答案1
得分: 1
"Fn() -> TR" 这个语法被展开成了 trait 约束 "Fn<(), Output = TR>"。"Output" 是一个关联类型。关联类型用于约束泛型参数,因此这是正确的。
但是在你的 trait 中,这不再是一个关联类型,而是一个类型参数。它们不会约束泛型参数,所以这会导致失败。
将其改为关联类型,就可以正常工作。
英文:
The syntax Fn() -> TR
is desugared into the trait bound Fn<(), Output = TR>
. Output
is an associated type. Associated types constrain generic parameters, so this is fine.
But with your trait, this is not an associated type anymore but a type parameter. They don't constrain generic parameters, so this fails.
Change it to be an associated type and it will work.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论