E3036

E3036 — A static call to a method several traits supply, where no impl takes the argument types written. Reported instead of an ambiguity (E3035), because ambiguity is not what went wrong: the call named one thing and the arguments ruled every candidate out. The message lists the impls that do exist, which is the edit.

What the compiler reports

E3036 … No impl of 'make' on 'i64' takes (i32) … implements Build<u16>, Build<u8>

The fragments the test suite holds the compiler to. An ellipsis marks text the test does not constrain; the emitted message also carries a source location.

A program that triggers it

//
// Part of the Vx Project, under the Apache License v2.0 with LLVM Exceptions.
// See LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// An untyped integer literal is i32, and no impl takes an i32.
//
// The narrowing that picks an impl by argument type leaves nothing here, and
// what went wrong is not ambiguity: the call named one method and the argument
// ruled every candidate out. So it reports what IS implemented, which is the
// edit -- annotate the literal, or write the missing impl.
//
// Rust answers the same program the same way, with E0277 on the bound that
// failed and a list of the impls that exist, rather than an ambiguity error.
//
// `u16` is declared first so the message has to list both: a candidate list
// that printed only the first impl would still satisfy a check naming `u8`.
//

trait Build<T> {
  fn make(v : T) -> Self;
}

impl Build<u16> for i64 {
  fn make(v : u16) -> i64 {
    return 16;
  }
}

impl Build<u8> for i64 {
  fn make(v : u8) -> i64 {
    return 8;
  }
}

fn main() -> i32 {
  print(i64::make(7));
  return 0;
}

From tests/frontend/fail/no_impl_takes_the_literals_fallback_type.vx, which asserts this diagnostic on every commit.

Related