Here are a few. If I think of other scenarios over the next few days I’ll try to add examples for them.
These examples should all allow their types to be elided:
const A: bool = true;
const B: i32 = 42i32;
const C: &str = "hello";
const D: (f32, f32) = (1.0f32, 2.0f32);
const E: [i64; 3] = [1i64, 2i64, 3i64];
// structs with explicit types on numeric arguments are definitely okay
struct Foo {
a: i32;
}
const F: Foo = Foo { a: 5i32 };
// slightly modified from an example @withoutboats provided on IRC
struct SomeType {
x: bool,
y: bool,
}
const INPUTS: &'static [(&'static str, SomeType)] =
&[("abc", SomeType { a: true, b: true}), ("def", SomeType { a: false, b: false}), ...];
Eliding types for string literals (as in C above) could be especially helpful for beginners to delay having to learn the nuances of Rust’s string-handling.
Type elisions on the following could do “the right thing” if fallback is used, but later changes to them could potentially cause issues that wouldn’t been immediately (although as @nikomatsakis points out, it’s unlikely a constant would be exported without being used AND have a type annotation added or removed):
const X: i32 = 5;
const Y: (f64, f64) = (1.0, 3.14);
The following examples would give the wrong type if fallback is used and their annotations are elided, although the typechecker would likely catch the issue, and programmers would likely expect the inferred types to differ from these annotations:
const Z: f32 = 2.5;
const W: [i16; 4] = [1, 2, 3, 4];
const V: (f32, f64) = (1.0, 5.4); // probably unlikely, but a possible unlikely case
Struct arguments are interesting, as well. For instance, consider these:
struct Foo {
a: i32
}
struct Bar {
a: i64
}
const F = Foo { a: 1 };
const G = Bar { a: 2 };
Both of those have a unique typing, so I think they should be acceptable. So to me, the main question around fallback is whether it should be used if the expression has multiple possible types (as in const N = 5).
Hmm, that’s tricky. I’ll have to give generic const functions more thought.