-
Notifications
You must be signed in to change notification settings - Fork 13.7k
Open
Labels
A-inferenceArea: Type inferenceArea: Type inference
Description
Prompted by @SkiFire13's suggestion in google/zerocopy#196 (comment).
I have the following code (minimized from the code linked above, so names will seem weird out of context; that doesn't have any bearing on the example):
use core::mem::MaybeUninit;
pub trait Projectable<F> {
type Inner;
}
impl<T, F> Projectable<F> for MaybeUninit<T> {
type Inner = T;
}
pub fn project<P, F, InnerToField>(
_outer: &P,
_inner_to_field: InnerToField,
)
where
P: Projectable<F>,
InnerToField: Fn(*const P::Inner) -> *const F,
{}
macro_rules! project {
(&$c:ident $($f:tt)*) => {{
unsafe {
project(
$c,
|inner| ::core::ptr::addr_of!((*inner) $($f)*),
)
}
}};
}
pub fn project_maybe_uninit_tuple(m: &MaybeUninit<(u8, u16)>) {
project!(&m.1)
}
This compiles fine. However, if I move the |inner| ...
closure to first be assigned to a variable:
macro_rules! project {
(&$c:ident $($f:tt)*) => {{
let inner_to_field = |inner| ::core::ptr::addr_of!((*inner) $($f)*);
unsafe {
project(
$c,
inner_to_field,
)
}
}};
}
...it results in a type inference failure:
error[[E0282]](https://doc.rust-lang.org/stable/error_codes/E0282.html): type annotations needed
--> src/lib.rs:22:60
|
22 | let inner_to_field = |inner| ::core::ptr::addr_of!((*inner) $($f)*);
| ^^^^^^^^ cannot infer type
...
34 | project!(&m.1)
| -------------- in this macro invocation
|
= note: this error originates in the macro `project` (in Nightly builds, run with -Z macro-backtrace for more info)
This is surprising to me, as the type constraints haven't changed at all. I'd assume that, if type inference had enough information to succeed with the first version of the code, it'd have enough information to succeed with the second version of the code.
Reporting this in case it's an inference bug.
Metadata
Metadata
Assignees
Labels
A-inferenceArea: Type inferenceArea: Type inference