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
A tour of VxThe chapter covering the rule this code enforces.
All diagnosticsEvery code the compiler can emit, grouped by stage.
E3019A
match arm whose integer literal cannot be represented in the scrutinee's type. The arm can never be selected, so the program does not mean what it says. Codegen used to parse the literal with a zero fallback, which turned an unrepresentable arm into a comparison against 0 — so the arm fired for scrutinee 0, the most common value there is, with no diagnostic.
E3020A match that no arm is guaranteed to match. A match over an enum must name every variant or carry a wildcard arm, wherever it sits. The uncovered value falls through, and when every written arm returns, the function falls off its end and hands back whatever was in the return slot. A scrutinee that is not an enum cannot be enumerated, so it is only asked for a wildcard in value position, where the fall-through edge would otherwise have no value to carry — codegen used to paper over that by evaluating the whole match to a constant zero.