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

Add empty structure/Remove structural records #5137

Closed
wants to merge 1 commit into from

Conversation

yjh0502
Copy link
Contributor

@yjh0502 yjh0502 commented Feb 27, 2013

The fix is straight-forward, but there are several changes
while fixing the issue.

  1. disallow mut keyword when making a new struct

In code base, there are following code,

struct Foo { mut a: int };
let a = Foo { mut a: 1 };

This is because of structural record, which is
deprecated corrently (see issue #3089) In structural
record, mut keyword should be allowd to control
mutability. But without structural record, we don't
need to allow mut keyword while constructing struct.

  1. disallow structural records in parser level
    This is related to 1). With structural records, there
    is an ambiguity between empty block and empty struct
    To solve the problem, I change parser to stop parsing
    structural records. I think this is not a problem,
    because structural records are not compiled already.

Misc. issues

There is an ambiguity between empty struct vs. empty match stmt.
with following code,

match x{} {}

Two interpretation is possible, which is listed blow

match (x{}) {} //  matching with newly-constructed empty struct
(match x{}) {}  //  matching with empty enum(or struct) x
                //  and then empty block

It seems that there is no such code in rust code base, but
there is one test which uses empty match statement:
https://github.com/mozilla/rust/blob/incoming/src/test/run-pass/issue-3037.rs

All other cases could be distinguished with look-ahead,
but this can't be. One possible solution is wrapping with
parentheses when matching with an uninhabited type.

enum what { }
fn match_with_empty(x: what) -> ~str {
    match (x) { //use parentheses to remove the ambiguity
    }
}

@yjh0502
Copy link
Contributor Author

yjh0502 commented Feb 27, 2013

Additional related issues:

#3192, #3089 (structural records is not compiled already), #4665 (also about structural records)

@yjh0502
Copy link
Contributor Author

yjh0502 commented Feb 27, 2013

Thanks for your review. I think this is a kind of a quick solution which could solve the problem by only changing a parser.
I think empty struct with destructor could be useful. Here's a code snippet that uses empty struct, which cannot be compiled without this patch and triggers me to submit the patch.

struct Defer {}
impl Drop for Defer {
    fn finalize(&self) { io::println("destroyed"); }
}
fn main() {
    let d = Defer{};
}

I also think that decision should be made by core team, whether just make empty struct impossible, add parentheses to use empty struct in match, or whatever. Could you let me know when a decision is made?

By the way, I just add another patch, which reverts merge failure. That's my mistake. If there is any other procedure to fix the merge failure problem (maybe submit a new pull request?), please let me know.

@nikomatsakis
Copy link
Contributor

Per this thread on the mailing list, I think the conclusion is that we will simply not parse empty structs like struct Foo {} at all. Instead, you should use the (existing and functional) syntax struct Foo;. You can then refer to an instance of this struct as Foo (note that since it has no fields, it is effectively a constant). This addresses the use case you mentioned and avoids the ambiguity, since Foo {} is not a valid struct literal.

That said, I am inclined to take this patch and address the matter of empty struct literals separately. I don't think there were invasive changes to the parser to handle the ambiguity as you did.

@nikomatsakis
Copy link
Contributor

I just opened issue #5167, which covers structs with no fields

@nikomatsakis
Copy link
Contributor

@yjh0502 I see that this pull request can no longer be automatically merged. Can you rebase it (and perhaps squash together the commit that undoes the broken merge with the other commits)? Otherwise bors won't be able to land it, even if we mark it r+.

@yjh0502
Copy link
Contributor Author

yjh0502 commented Mar 1, 2013

I aggregate & clean up all commit, and make it to single commit. Sorry for late replay, I'm not yet familier with git & github, so it takes time.
I split the patch into two, one is clean-up of original patch, and the other is a roll-back for empty struct literals. As discussed in the mailing list, I revert changes on a parser: now parser itself works as before for struct literals.

@nikomatsakis
Copy link
Contributor

OK. One last thing: can you squash those two commits together (since one just undoes part of the other) and also revert back the tests which were changed:

  • src/test/run-pass/issue-3037.rs
  • src/test/run-pass/issue-1460.rs
  • src/test/compile-fail/while-type-error.rs
  • src/test/compile-fail/liveness-while-cond.rs
  • src/test/compile-fail/issue-3096-2.rs
  • src/test/compile-fail/if-typeck.rs

Thanks.

@yjh0502
Copy link
Contributor Author

yjh0502 commented Mar 2, 2013

Done.

bors added a commit that referenced this pull request Mar 2, 2013
The fix is straight-forward, but there are several changes
while fixing the issue.

1) disallow `mut` keyword when making a new struct

In code base, there are following code,

```rust
struct Foo { mut a: int };
let a = Foo { mut a: 1 };
```

This is because of structural record, which is
deprecated corrently (see issue #3089) In structural
record, `mut` keyword should be allowd to control
mutability. But without structural record, we don't
need to allow `mut` keyword while constructing struct.

2) disallow structural records in parser level
This is related to 1). With structural records, there
is an ambiguity between empty block and empty struct
To solve the problem, I change parser to stop parsing
structural records. I think this is not a problem,
because structural records are not compiled already.

Misc. issues

There is an ambiguity between empty struct vs. empty match stmt.
with following code,

```rust
match x{} {}
```

Two interpretation is possible, which is listed blow

```rust
match (x{}) {} //  matching with newly-constructed empty struct
(match x{}) {}  //  matching with empty enum(or struct) x
                //  and then empty block
```

It seems that there is no such code in rust code base, but
there is one test which uses empty match statement:
https://github.com/mozilla/rust/blob/incoming/src/test/run-pass/issue-3037.rs

All other cases could be distinguished with look-ahead,
but this can't be. One possible solution is wrapping with
parentheses when matching with an uninhabited type.

```rust
enum what { }
fn match_with_empty(x: what) -> ~str {
    match (x) { //use parentheses to remove the ambiguity
    }
}
```
@bors bors closed this Mar 2, 2013
bors added a commit to rust-lang-ci/rust that referenced this pull request May 2, 2020
Prevent failing to restart setup-toolchain

If `rustup-toolchain-install-master` fails to install master
toolchain (in case `rustup update` executes at the same remove the
tmp directory), `cargo search` (which use master toolchain after
`rustup override` command) will fail. This leads to setup-toolchain
fails too.

changelog: none
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants