New Issue: [Bug]: incorrectly allowed to use values to specify types

28160, "jabraham17", "[Bug]: incorrectly allowed to use values to specify types", "2025-12-09T00:30:25Z"

The following program compiles and works

proc foo(): true {
  return false;
}
proc bar(): 2 {
  return 17;
}
proc myParam() param do return "world";
proc baz(): myParam() {
  return "hello";
}
proc myRange() do return 1..10;
proc qux(): myRange() {
  return 5..10;
}
proc egg(): (1,2) {
  return (3,4);
}
record R {}
proc eggy(): new R() {
  return new R();
}

writeln(foo());
writeln(bar());
writeln(baz());
writeln(qux());
writeln(egg());
writeln(eggy());

None of these functions are correct, you should not be able to specify a value (param, literal, or otherwise) as the return type. But the compiler accepts this as valid.

Similarly, I can use values to specify formal types

proc foo(x: true) {
  return false;
}
proc bar(x: 2) {
  return 17;
}
// function calls get proper errors
// proc myParam() param do return "world";
// proc baz(x: myParam()) {
//   return "hello";
// }
// function calls get proper errors
// proc myRange() do return 1..10;
// proc qux(x: myRange()) {
//   return 5..10;
// }
// tuple literals are desugared to function calls and get proper errors
// proc egg(x: (1, 2)) {
//   return (3,4);
// }

proc foobar(x: "world") {
  return "hello";
}
// range literals are desugared to function calls and get proper errors
// proc bazaar(x: 1..5) {
//   return 10..15;
// }
record R {}
proc eggy(x: new R()) {
  return new R();
}

writeln(foo(false));
writeln(bar(3));
// writeln(baz("there"));
// writeln(qux(1..10));
// writeln(egg((2, 3)));
writeln(foobar("there"));
// writeln(bazaar(5..10));
writeln(eggy(new R()));

Things are slightly better here, as non-literals seem to have special error handling. For example, trying to call a function as the formal type gets the error The declared type of the formal x is given by non-type function '....'

The same problem exists with variable declarations, although I didn't do as exhaustive of testing

proc foo() do return 0;
var x: foo() = 1;
writeln(x);
var y: 2 = 3;
writeln(y);

All of the code snippets above compile and run without issue, where they should be errors. With Dyno, some of these show up properly as errors. The variables snippet is resolved by dyno as an error, "cannot use a value as a type". Others, like the return types, cause dyno internal errors

proc foo(): true {
  return false;
}
writeln(foo()); //  Assertion failed: param_ == nullptr || kind_ == Kind::PARAM