E3016

E3016 — A generic call that leaves one of the callee's type parameters unbound: no argument fixes it, and no type declared for the result does either. Left alone, the parameter travelled into the instance's symbol name as its bare letter and sizeof<T>() folded to 8, so a buffer was sized for an element type that was never chosen. Spell the type argument out, as Vec<i32>::new(), or give the result a type, as let v : Vec<i32> = Vec::new();.

What the compiler reports

E3016{{.*}}Type parameter 'T' of 'Holder::width' is not determined by this call

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
//
//
// A generic call that binds none of its type parameters is refused in the frontend. Before,
// nothing refused it: the unbound `T` travelled into the instance's symbol name as the letter
// T, and `sizeof<T>()` inside it folded to 8, so a buffer was sized for an element type that
// was never chosen. Both call shapes that build such an instance are pinned: a method named
// through its type, and a generic free function.

struct Holder<T> {
  v : T,
}

impl<T> Holder<T> {
  fn width() -> i64 {
    return sizeof<T>();
  }
}

fn free_width<T>() -> i64 {
  return sizeof<T>();
}

fn main() -> i32 {
  // No argument mentions `T`, and the declared result type `i64` does not either. Each call
  // is reported once: the binding does not go on to complain that its initializer has no type.
  let a : i64 = Holder::width();
  let b : i64 = free_width();
  return (a + b) as i32;
}

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

Related