> keywords like "let" are extra work for the programmer because the compiler can infer them automatically.

I strongly disagree. In my experience scope inference either completely blows (javascript, coffeescript), sucks (python) or requires language asymmetries (ruby). Either way, I've come to see it as an awful idea.

> I’m not a fan of printf()-style parameters, because they break ordering (remarkably, php does this best with its “.” and “$” notations).

Rust does not use printf-style parameters, it uses C#-style parameters[0] (also used in Python's "new" str.format[1][2]). The format placeholders can explicitly specify the parameter index (in whatever order, e.g. "{1} {3} {0} {2}") or name ("{foo} {bar} {baz}"). See third and fourth println! of the second page.

> I’m not a fan of the generics syntax, borrowed from templates in c++ (I prefer the something like the “auto” style more, shifting work to the compiler).

?

Rust already has local type inference (which is what `auto` does), generics syntax is orthogonal to TI.

> Forcing the programmer to manually place values on the heap with “~” is annoying, when other languages can automatically optimize such things.

The whole point there is to have the developer knowingly decide whether they want allocation on the stack, the heap or somewhere else (managed or refcounted heaps are/will be available[3]). Rust is aiming at C++'s niche, not Java, having the language heap-allocate by default and try to guess if it could just stack-allocate wouldn't work.

> Lifetimes completely confuse me, as it seems like they would be handled by garbage collection?

Rust's GC is optional, and most of the standard library (and as experience shows libraries and code bases) can avoid GC. The point of lifetime is to avoid both mandatory GC and manual memory management (à la C): if the compiler knows when an object completely stops being used, it can automatically and safely release even heap-allocated objects.

> I might have gone with traits (interfaces) everywhere instead of distinguishing them from structs, because that seems to be the direction the world is going, to avoid inheritance problems.

Where do data members (attributes) live if you don't have structs?

> #[bench] seems a little weird (putting profiling calls in the code), although I do find myself wanting this constantly, so if they conditionally compile they could be handy.

#[bench] is a specialisation (of sorts) of #[test], it's only compiled in when using --test, and run when passing —bench to the resulting test harness. see http://static.rust-lang.org/doc/0.10/guide-testing.html#micr...

Note that it's not a profiling call, it doesn't profile anything (unless you enable the profiler while running the bench), it only provides coarse/toplevel timing information, like python's timeit or ruby's Benchmark

[0] http://msdn.microsoft.com/en-us/library/system.string.format...

[1] https://docs.python.org/3/library/string.html#formatstrings

[2] technically it's probably Python's version, IIRC C# requires the index and has no support for name-based parameters

[3] and maybe user-provided boxes, such as a zeroing box (to store cryptographic keys) or a GPU box, or local v remote for clusters, the sky's the limit