Description
I'm getting this warning:
warning: broken MIR (Terminator { source_info: SourceInfo { span: src/array.rs:50:24: 50:89, scope: scope1 }, kind: _3 = std::ptr::read::<array::Array<<tll::ternary::Zero<L> as tll::ternary::NatPred>::Output, T>>(_5) -> [return: bb5, unwind: bb4] }): call dest mismatch (array::Array<<tll::ternary::Zero<L> as tll::ternary::NatPred>::Output, T> <- array::Array<tll::ternary::Two<<L as tll::ternary::NatPred>::Output>, T>): Sorts(ExpectedFound { expected: <tll::ternary::Zero<L> as tll::ternary::NatPred>::Output, found: tll::ternary::Two<<L as tll::ternary::NatPred>::Output> })
--> src/array.rs:50:34
|
50 | let init = ptr::read(&self as *const Self as *const Array<Pred<Zero<L>>, T>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: broken MIR (Terminator { source_info: SourceInfo { span: src/array.rs:50:24: 50:89, scope: scope1 }, kind: _3 = std::ptr::read::<array::Array<<tll::ternary::Zero<L> as tll::ternary::NatPred>::Output, T>>(_5) -> [return: bb5, unwind: bb4] }): bad arg #0 (*const array::Array<tll::ternary::Two<<L as tll::ternary::NatPred>::Output>, T> <- *const array::Array<<tll::ternary::Zero<L> as tll::ternary::NatPred>::Output, T>): Sorts(ExpectedFound { expected: tll::ternary::Two<<L as tll::ternary::NatPred>::Output>, found: <tll::ternary::Zero<L> as tll::ternary::NatPred>::Output })
--> src/array.rs:50:34
|
50 | let init = ptr::read(&self as *const Self as *const Array<Pred<Zero<L>>, T>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: broken MIR (_23 = _3): bad assignment (array::Array<tll::ternary::Two<<L as tll::ternary::NatPred>::Output>, T> = array::Array<<tll::ternary::Zero<L> as tll::ternary::NatPred>::Output, T>): Sorts(ExpectedFound { expected: tll::ternary::Two<<L as tll::ternary::NatPred>::Output>, found: <tll::ternary::Zero<L> as tll::ternary::NatPred>::Output })
--> src/array.rs:54:14
|
54 | (init, last)
The types in question check out when I look at them; tll::ternary::...
types and traits are from a type-level implementation of natural numbers represented in a ternary format. What's going on is that on the left-hand of these "type mismatches" is that one side has gone through normalization and the other has not (Pred<Zero<L>>
should normalize to Two<Pred<L>>
.) So, my (un)educated guess as to what's going on here is that normalization is not happening somewhere it should, and as such MIR is producing a spurious warning about a type mismatch.
Here's the code that causes it. Unfortunately, I don't think I can easily pare this down to a minimal reproduction case, but to start:
impl<L: Arrayify<T> + NatPred, T> Array<Zero<L>, T>
where Pred<L>: Arrayify<T>
{
fn split_last(self) -> (Array<Pred<Zero<L>>, T>, T) {
unsafe {
let init = ptr::read(&self as *const Self as *const Array<Pred<Zero<L>>, T>);
let last = ptr::read((&self as *const Self as *const T)
.offset(L::reify() as isize - 1));
mem::forget(self);
(init, last)
}
}
}
Changing the code to this compiles just fine with no broken MIR warnings:
impl<L: Arrayify<T> + NatPred, T> Array<Zero<L>, T>
where Pred<L>: Arrayify<T>
{
fn split_last(self) -> (Array<Pred<Zero<L>>, T>, T) {
unsafe {
let init = ptr::read(&self as *const Self as *const Array<Two<Pred<L>>, T>);
let last = ptr::read((&self as *const Self as *const T)
.offset(L::reify() as isize - 1));
mem::forget(self);
(init, last)
}
}
}
Compiler info
sean@sean-Samus:~/Projects/tll-array$ rustc --version --verbose
rustc 1.15.0-nightly (908dba0c9 2016-12-01)
binary: rustc
commit-hash: 908dba0c9477b7dd022a236cb1514ddfca9369f2
commit-date: 2016-12-01
host: x86_64-unknown-linux-gnu
release: 1.15.0-nightly
LLVM version: 3.9