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

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

Closed
nikomatsakis opened this issue Aug 18, 2012 · 1 comment
Labels
A-type-system Area: Type system I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️

Comments

@nikomatsakis
Copy link
Contributor

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));
            }
          }
          _ => ()
        }
      }
@msullivan
Copy link
Contributor

I can take this. I touched some code that computed the bounds for method calls recently; I'll abstract that out and fix this vtable stuff to use it.

@ghost ghost assigned msullivan Aug 20, 2012
bors pushed a commit to rust-lang-ci/rust that referenced this issue May 15, 2021
RalfJung pushed a commit to RalfJung/rust that referenced this issue Dec 26, 2023
jaisnan pushed a commit to jaisnan/rust-dev that referenced this issue Jul 29, 2024
…rust-lang#3221)

Resolves rust-lang#2975

This PR makes Kani able to check if a raw pointer is valid before
casting it to a reference.

To check for the pointer validity when casting it to a reference, inject
asserting `__CPROVER_r_ok(ptr, sz)` into places where a raw pointer is
dereferenced and a reference is immediately taken.

Since this check seems to cause some of the CIs to run out of memory, it
is only enabled under `-Z ptr-to-ref-cast-checks` flag.

By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-type-system Area: Type system I-ICE Issue: The compiler panicked, giving an Internal Compilation Error (ICE) ❄️
Projects
None yet
Development

No branches or pull requests

2 participants