Skip to content

Both operands to ICmp instruction are not of the same type! #2149

Description

@jruderman
iface monad<A> {
    fn bind<B>(fn(A) -> self<B>);
}
impl monad<A> of monad<A> for [A] {
    fn bind<B>(f: fn(A) -> [B]) {
        let mut r = fail;
        for self.each {|elt| r += f(elt); }
    }
}
fn main() {
    ["hi"].bind {|x| [x] };
}

rustc fails with:

Assertion failed: (getOperand(0)->getType() == getOperand(1)->getType() && "Both operands to ICmp instruction are not of the same type!"), function ICmpInst, file /Users/jruderman/code/rust/src/llvm/include/llvm/Instructions.h, line 958.

Activity

  1. nikomatsakis commented on Apr 7, 2012

    @nikomatsakis
    Contributor

    I suspect that this, #2150, and #2151 are all a result of a (perhaps poor) decision I made to resolve unconstrained types to bottom. I think I will revert that choice. It means that some nonsensical programs (like these) will not compile but also that something like "let x = none;" where there is no further constraint on the type of x will fail, because it will not know what sort of "none" x is (e.g., option<int> etc). The latter is how things used to be and is tolerable in practice...I only put in the "unresolved types become bot" rule because some programs that used to work (which contained unconstrained types) now failed, but they were all nonsensical (generated by the fuzzer) to begin with.

  2. jruderman commented on Apr 7, 2012

    @jruderman
    ContributorAuthor

    Could allow let x = none; to compile as if x were option<()> while still rejecting let x = fail;?

  3. nikomatsakis commented on Apr 7, 2012

    @nikomatsakis
    Contributor

    Hmm, I could be wrong in my theory, actually. I'm not 100% sure why r += f(elt) compiles. I would expect that to error out right now, since the type of r is completely unknown at that point.

  4. nikomatsakis commented on Apr 7, 2012

    @nikomatsakis
    Contributor

    @jruderman well one possible fix along those lines, which I just implemented, is to refuse to consider the "bottom" type as "resolved"---this causes this test (and the others) to result in a compile error, because a resolved type is required in order to process a binary operator. (resolved types are required wherever the resulting type of an expression is overloaded based on an input type; this occurs for binary operators because of overloaded operators and because not all types are addable and so forth) I am not sure if this is the best fix---it may leave other weird paths through the compiler---but I guess I will institute it for now.

  5. added a commit that references this issue on Sep 22, 2022
  6. added a commit that references this issue on Jun 27, 2026
  7. added a commit that references this issue on Aug 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-codegenArea: Code generation

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions