Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grammar inconsistencies with empty blocks {} and semi-colons. #7981

Closed
brendanzab opened this issue Jul 23, 2013 · 14 comments
Closed

Grammar inconsistencies with empty blocks {} and semi-colons. #7981

brendanzab opened this issue Jul 23, 2013 · 14 comments
Labels
A-grammar Area: The grammar of Rust

Comments

@brendanzab
Copy link
Member

struct A;           // ok
impl A;             // ok
trait B;            // error - must be `trait B {}`
impl B for A;       // ok
enum C;             // error - must be `enum C {}`
extern;             // error - must be `extern {}`
fn foo();           // error - must be `fn foo() {}`

The error on fn foo(); should probably stay, but I've included it for completion sake.

@bstrie
Copy link
Contributor

bstrie commented Jul 23, 2013

Nominating for Well-Defined.

@emberian
Copy link
Member

All of these make sense, but they are inconsistent.

@catamorphism
Copy link
Contributor

Accepted for well-defined

@brson
Copy link
Contributor

brson commented Sep 12, 2013

I don't think the block-less fn or extern make sense, but agree the others should allow no block.

@thestinger
Copy link
Contributor

A block-less function would be ambiguous in traits.

@alexcrichton
Copy link
Member

I've opened #9336 to disallows impl ...; because I think those should follow the pattern of "requiring braces".

I believe that struct A; should be valid, however, because our syntax for tuple-structs is struct A(...); (note the semicolon). If you leave off the tuple, then it seems like it'd make sense to still retain the semicolon.

Basically, I would consider #9336 as closing this issue, but others may feel differently.

@lilyball
Copy link
Contributor

I agree with @alexcrichton. struct A; makes sense to leave as-is, everything else should be disallowed.

@brson
Copy link
Contributor

brson commented Sep 19, 2013

I guess we should discuss this in the meeting.

@sfackler
Copy link
Member

It'd also be nice if struct Foo {} were legal. Is there a good reason that the compiler specifically forbids it?

@nikomatsakis
Copy link
Contributor

Foo { } as an expression literal is ambiguous in the parser, I believe, though I can't remember why.

@Kimundi
Copy link
Member

Kimundi commented Sep 24, 2013

The problem are cases like this:

match Foo { } { }

See #3212, #3192 and #5167

@Kimundi
Copy link
Member

Kimundi commented Sep 24, 2013

Why do we want to forbid impl ...; ? It could be very useful for traits that only "tag" a type, without actually adding new functionality.

I also think that allowing enum ...; to define an custom uninhabited type should be legal and would be useful.

What makes sense to me:

struct A;           // allow
struct A{}          // forbid because ambiguity
impl A;             // allow
impl A{}            // allow
trait B;            // allow
trait B{}           // allow
impl B for A;       // allow
impl B for A{}      // allow
enum C;             // allow
enum C{}            // allow
extern;             // forbid, useless
extern{}            // forbid, useless
fn foo(){}          // allow
fn foo();           // forbid, ambiguous in traits

The reasoning behind allowing both variants for most of the cases is that there are two possible situations:

  1. You intentionally declared an item as being empty. Then ; is shorter, and familiar from the struct neccessarity.
  2. You're re factoring your code or are in the process of writing it, and your item either doesn't contain anything yet or all code is currently commented out. Needing to replace the {} with ; back and forth in those cases would be irritating.

(Unless the limitation for unit structs is also a problem for enum or trait definitions, then they need to be forbidden too)

@alexcrichton
Copy link
Member

The main reason for forbidding it is consistency. Right now these all mean the same thing, so why not have only one way to do them? In the future we could decide to make ; and {} have separate meanings on a per-item basis, but for now we think it's best to forbid ; where it's not necessary.

alexcrichton added a commit to alexcrichton/rust that referenced this issue Sep 24, 2013
bors added a commit that referenced this issue Sep 24, 2013
Progress on #7981

This doesn't completely close the issue because `struct A;` is still allowed, and it's a much larger change to disallow that. I'm also not entirely sure that we want to disallow that. Regardless, punting that discussion to the issue instead.
@alexcrichton
Copy link
Member

Closed by #9336

joshuafleck added a commit to meetcleo/re_dms that referenced this issue Sep 27, 2021
flip1995 pushed a commit to flip1995/rust that referenced this issue Nov 23, 2021
Add new lint `octal_escapes`

This checks for sequences in strings that would be octal character
escapes in C, but are not supported in Rust.  It suggests either
to use the `\x00` escape, or an equivalent hex escape if the octal
was intended.

Fixes rust-lang#7981

---

*Please write a short comment explaining your change (or "none" for internal only changes)*

changelog: Add new lint [`octal_escapes`], which checks for literals like `"\033[0m"`.
joshuafleck added a commit to meetcleo/re_dms that referenced this issue Aug 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-grammar Area: The grammar of Rust
Projects
None yet
Development

No branches or pull requests