Only one obvious way for Vec literals?

In my opinion some parts of the Python Zen are good for more than just Python. One of its rules says “There should be one-- and preferably only one --obvious way to do it.”. Currently rustc accepts syntax like this with no warnings:

#![allow(unused_variables)]
fn main() {
    let a = vec![1, 2];
    let b = vec!(1, 2);
    let c = vec!{1, 2};
}

vec! is a macro, and that kind of Rust macros allow the use of () [] and {}. But is it a good idea to allow slightly different syntaxes for a such common collection literal as a Vec? My gut says that having only one way of writing vec literals is better.

rustfmt converts the () and {} of vec literals to [].

In other situations Rustc gives vigorous warnings (and I like that) for small syntactic problems:

#![allow(unused_variables)]
fn main() {
    let a = if (true) { 0 } else { 1 };
    while (true) {}
    let x = (1 + 1);
}

Gives:

warning: unnecessary parentheses around `if` condition
 --> ...\test.rs:3:16
  |
3 |     let a = if (true) { 0 } else { 1 };
  |                ^^^^^^ help: remove these parentheses
  |
  = note: #[warn(unused_parens)] on by default

warning: unnecessary parentheses around `while` condition
 --> ...\test.rs:4:11
  |
4 |     while (true) {}
  |           ^^^^^^ help: remove these parentheses

warning: unnecessary parentheses around assigned value
 --> ...\test.rs:5:13
  |
5 |     let x = (1 + 1);
  |             ^^^^^^^ help: remove these parentheses

warning: denote infinite loops with `loop { ... }`
 --> ...\test.rs:4:5
  |
4 |     while (true) {}
  |     ^^^^^^^^^^^^ help: use `loop`
  |
  = note: #[warn(while_true)] on by default

So is it a good idea to add a warning to rustc that suggest to always use [] for vec literals?

3 Likes

I wonder if macros 2.0 could fix this issue in general. The obvious rule is to require braces on the definition site and on the call site to match.

5 Likes

Yes, the plan was to “fix” this in declarative macros 2.0 somehow.

5 Likes

I thought this was just a side-effect of how macros currently work. Basically they operate entirely with “token trees” (anything inside a set of curly braces, parens, or square brackets). By the time the token tree reaches a macro any information about what type of delimiter was used ((), [], or {}) is effectively erased.

As such you can use macros with any delimiter you want (as long as they match up, obviously) and the macro/rustc won’t care.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.