【发布时间】:2021-12-31 03:33:53
【问题描述】:
我有一个类型 Builder 和一个通用关联类型 (GAT) InstanceForBuilder<'a>。
我想编写一个函数 (build_with_42_for_bool<Builder>),将 Builder 限制为仅适用于 Builder::InstanceForBuilder<'a>::InstanceProperty == bool 的情况(适用于所有 'a)。
我已经玩了一段时间来正确地了解这个 for <'a> 的语法,但一直无法完成这项工作。
生命周期不能是函数本身的模板参数,因为引用只存在于其中。
鉴于 GAT 是一个不稳定的功能,这是否可能?
#![feature(generic_associated_types)]
// Trait definitions.
trait Builder {
type InstanceForBuilder<'a>: Instance<'a>;
fn build<'a>(&self, val: &'a usize) -> Self::InstanceForBuilder<'a>;
}
trait Instance<'a> {
// Some functions will only work when the instance has some concrete associated type.
type InstanceProperty;
}
fn build_with_42_for_bool<B: Builder>(builder: B)
where
// TODO: What do I put here to make this work?
for<'a> B::InstanceForBuilder<'a>: Instance<'a, InstanceProperty = bool>,
{
builder.build(&42);
// Do some testing here. The Instance won't be returned.
}
// Now try it out.
struct MyBuilder;
struct MyInstance<'a> {
val: &'a usize,
}
impl Builder for MyBuilder {
type InstanceForBuilder<'a> = MyInstance<'a>;
fn build<'a>(&self, val: &'a usize) -> Self::InstanceForBuilder<'a> {
MyInstance { val }
}
}
impl<'a> Instance<'a> for MyInstance<'a> {
type InstanceProperty = bool;
}
fn main() {
let builder = MyBuilder;
build_with_42_for_bool(builder); // TODO: Doesn't work
}
在我的实际代码中,build_with_42_for_bool 是一个测试助手,它以特定方式构造传递给build 的参数。现在我可能只是在任何地方内联该函数,因为唯一的问题是如何指定这个函数的生命周期。代码本身运行良好。
这是完整的错误:
Compiling pairwise-aligner v0.1.0 (/home/philae/git/eth/git/astar-pairwise-aligner)
error[E0271]: type mismatch resolving `for<'a> <<_ as Builder>::InstanceForBuilder<'a> as Instance<'a>>::InstanceProperty == bool`
--> examples/test.rs:45:5
|
45 | build_with_42(builder); // TODO: Doesn't work
| ^^^^^^^^^^^^^ expected `bool`, found associated type
|
= note: expected type `bool`
found associated type `<<_ as Builder>::InstanceForBuilder<'_> as Instance<'_>>::InstanceProperty`
= help: consider constraining the associated type `<<_ as Builder>::InstanceForBuilder<'_> as Instance<'_>>::InstanceProperty` to `bool`
= note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html
note: required by a bound in `build_with_42`
--> examples/test.rs:19:53
|
16 | fn build_with_42<B: Builder>(builder: B)
| ------------- required by a bound in this
...
19 | for<'a> B::InstanceForBuilder<'a>: Instance<'a, InstanceProperty = bool>,
| ^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `build_with_42`
error[E0271]: type mismatch resolving `for<'a> <MyBuilder as Builder>::InstanceForBuilder<'a> == <MyBuilder as Builder>::InstanceForBuilder<'a>`
--> examples/test.rs:45:5
|
45 | build_with_42(builder); // TODO: Doesn't work
| ^^^^^^^^^^^^^ type mismatch resolving `for<'a> <MyBuilder as Builder>::InstanceForBuilder<'a> == <MyBuilder as Builder>::InstanceForBuilder<'a>`
|
note: expected this to be `<MyBuilder as Builder>::InstanceForBuilder<'a>`
--> examples/test.rs:32:35
|
32 | type InstanceForBuilder<'a> = MyInstance<'a>;
| ^^^^^^^^^^^^^^
= note: expected associated type `<MyBuilder as Builder>::InstanceForBuilder<'a>`
found struct `MyInstance<'a>`
help: a method is available that returns `<MyBuilder as Builder>::InstanceForBuilder<'a>`
--> examples/test.rs:8:5
|
8 | fn build<'a>(&self, val: &'a usize) -> Self::InstanceForBuilder<'a>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ consider calling `Builder::build`
note: required by a bound in `build_with_42`
--> examples/test.rs:19:40
|
16 | fn build_with_42<B: Builder>(builder: B)
| ------------- required by a bound in this
...
19 | for<'a> B::InstanceForBuilder<'a>: Instance<'a, InstanceProperty = bool>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `build_with_42`
For more information about this error, try `rustc --explain E0271`.
error: could not compile `pairwise-aligner` due to 2 previous errors
【问题讨论】:
标签: rust associated-types