Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
sdleffler opened this issue Dec 2, 2016 · 0 comments
Closed

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

sdleffler opened this issue Dec 2, 2016 · 0 comments
Assignees

Comments

@sdleffler
Copy link
Contributor

sdleffler commented Dec 2, 2016

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
@arielb1 arielb1 self-assigned this Feb 28, 2017
arielb1 added a commit to arielb1/rust that referenced this issue Mar 1, 2017
bors added a commit that referenced this issue Mar 4, 2017
More through normalization, Feb/Mar 2017 edition

Fix a few normalization bugs.

Fixes #27901.
Fixes #28828.
Fixes #38135.
Fixes #39363.
Fixes #39367.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants