Skip to content

vtable resolution does not take place for calls that are not statically resolved #3221

Closed
@nikomatsakis

Description

@nikomatsakis

Vtable resolution ignores calls to methods on type parameters or traits. If the methods themselves take bounded type parameters, this leads to ICEs in trans because the requisite information is not found.

Consider this example:

trait TraitA {
    fn method_a() -> int;
}

trait TraitB {
    fn gimme_an_a<A: TraitA>(a: A) -> int;
}

impl int: TraitB {
    fn gimme_an_a<A: TraitA>(a: A) -> int {
        a.method_a() + self
    }
}

fn call_it<B: TraitB>(b: B)  -> int {
    let y = 4u;
    b.gimme_an_a(y)
}

fn main() {
    let x = 3i;
    assert call_it(x) == 22;
}

Here, the call_it() function should not compile, because gimme_an_a() demands a type which implements the interface TraitA---of which there are no implementations! Still it compiles. Bad.

The relevant code is in rustc::middle::typeck::check::vtable::resolve_expr(), which ignores all cases other than method_static:

      ast::expr_field(*) | ast::expr_binary(*) |
      ast::expr_unary(*) | ast::expr_assign_op(*) |
      ast::expr_index(*) => {
        match cx.method_map.find(ex.id) {
          some({origin: method_static(did), _}) => {
            let bounds = ty::lookup_item_type(cx.tcx, did).bounds;
            if has_trait_bounds(*bounds) {
                let callee_id = match ex.node {
                  ast::expr_field(_, _, _) => ex.id,
                  _ => ex.callee_id
                };
                let substs = fcx.node_ty_substs(callee_id);
                cx.vtable_map.insert(
                    callee_id,
                    lookup_vtables(fcx, ex, bounds,
                                   &substs, false));
            }
          }
          _ => ()
        }
      }

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-type-systemArea: Type systemI-ICEIssue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions