Skip to content

Broken MIR stemming from (potentially spurious?) type error #38135

Closed
@sdleffler

Description

@sdleffler

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions