Skip to content

Wrong error message trying to initialise an empty struct  #3192

Closed
@bblum

Description

@bblum
Contributor

Updated bug report

Compiling this (erroneous) program:

struct mutex;
fn main() {
    let x = mutex { }; // this should be `let x = mutex;`
    println(fmt!("%?", x));
}

yields:

/tmp/foo.rs:3:18: 3:19 error: expected `;` but found `{`
/tmp/foo.rs:3     let x = mutex { };

We currently emit a nice error message if you incorrectly write the struct mutex definition as:

struct mutex { }

that tells you that you need to write the Unit-like struct as struct mutex;; we should do the same for the struct initialization expression.

Original bug report

struct mutex { }
fn main() {
    let x = mutex { };
}

gives:

struct.rs:3:18: 3:19 error: expected `;` but found `{`
struct.rs:3     let x = mutex { };

but if you comment out the let x line, it gives:

struct.rs:1:0: 1:16 error: a class must have at least one field
struct.rs:1 struct mutex { }

Personally, I think we should be allowed to have empty structs, but either way, the latter error message should have higher priority(?) than the former.

Activity

catamorphism

catamorphism commented on Aug 13, 2012

@catamorphism
Contributor

Parsing happens before typechecking, and the "at least one field" error is a type error. So this won't change.

We discussed it a while ago and agreed to disallow empty structs, but if you want to reopen the discussion, feel free to file a separate RFC bug.

bblum

bblum commented on Aug 13, 2012

@bblum
ContributorAuthor

@catamorphism Maybe the parser could allow mutex { }, so that it doesn't fail until typechecking?

catamorphism

catamorphism commented on Aug 13, 2012

@catamorphism
Contributor

Sorry, I was reading too fast and didn't understand at first that the parser is essentially checking for the same thing that the typechecker is.

That seems reasonable to me.

bblum

bblum commented on Aug 22, 2012

@bblum
ContributorAuthor

I attempted to fix this. Something like (libsyntax/parse/parse.rs):

1007                 // This might be a struct literal.
1008                 if self.looking_at_record_literal() {
1009 +------ 27 lines: It's a struct literal.---------------------------------------------
1036                 } else if self.look_ahead(1) == token::RBRACE {   // (Code I added starts here)
1037                     // It's an empty struct literal.
1038                     // I'd handle this condition in looking_at_record, but
1039                     // empty records are ambiguous with empty blocks.
1040                     self.bump();
1041                     ex = expr_struct(pth, ~[], none);
1042                     return self.mk_pexpr(lo, hi, ex);   // (ends here)
1043                 }

But it seems like this makes the grammar ambiguous with empty-bodied 'do' statements -- do unkillable { } failed to parse.

I wonder if this will stop being ambiguous once type names have to be camel case?

nikomatsakis

nikomatsakis commented on Aug 22, 2012

@nikomatsakis
Contributor

Type names will never have to be camel case---that's intended to be a convention. I think that's a known ambiguity that was supposed to be resolved by do (and for) favoring one interpretation. @pcwalton can confirm (I know we did discuss it). We could always require parentheses in do/for to remove the ambiguity, but that would mean:

do spawn() { ... }

Which, admittedly, is not so bad.

bblum

bblum commented on Aug 22, 2012

@bblum
ContributorAuthor

it occurred to me that the grammar might not have to be ambiguous after all, and it was just my fix that was wrong. we have something like:

e := { expr* }
   | do path[(expr*)] [|ident*|] expr
   | path { (ident:expr)* }

and do path { } got confused with path { }. i think to resolve it, either parsing do should use lookahead in the same way as my code above, or my code above should somehow have lower priority. the latter seems better, but i'm not sure how it would be written.

pcwalton

pcwalton commented on May 16, 2013

@pcwalton
Contributor

I think this bug is just asking for a better parser error message when you try to create an empty structure. That doesn't seem backwards incompatible to me. Renominating.

graydon

graydon commented on Jun 13, 2013

@graydon
Contributor

just a bug, removing milestone/nomination.

pnkfelix

pnkfelix commented on Aug 8, 2013

@pnkfelix
Member

Visiting for triage email from 2013-07-29.

I think I can revise the parser in a disciplined manner to put in a better error message (as pcwalton suggested). I spent some time Monday hacking on that, I'll have a draft up for people to look at soon.

added a commit that references this issue on Aug 12, 2013

auto merge of #8418 : pnkfelix/rust/fsk-issue3192-improve-parse-error…

de48274

2 remaining items

added a commit that references this issue on Oct 9, 2013

Fix for rust-lang#3192 that is semi-melded with a Tracing infrastruct…

added a commit that references this issue on Feb 17, 2024

Auto merge of rust-lang#3192 - eduardosm:x86-avx-intrinsics, r=RalfJung

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-frontendArea: Compiler frontend (errors, parsing and HIR)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @graydon@nikomatsakis@pcwalton@pnkfelix@catamorphism

      Issue actions

        Wrong error message trying to initialise an empty struct · Issue #3192 · rust-lang/rust