gccrs icon indicating copy to clipboard operation
gccrs copied to clipboard

Assigning structs to variables

Open liamnaddell opened this issue 1 year ago • 7 comments

Summary

gccrs lets you assign structs to variables, when rustc emits "expected value, found struct ..."

Reproducer

I tried this code:

struct A {
    a: u32,
}

fn main() {
    let a = A {a: 4};
    let b = A;
    a.a = 2;
}

Does the code make use of any (1.49) nightly feature ?

  • [ ] Nightly

Godbolt link

No response

Actual behavior

The current behavior is...

The code compiles.

Expected behavior

I expected to see...

error[E0423]: expected value, found struct `A`
 --> main.rs:7:13
  |
1 | / struct A {
2 | |     a: u32,
3 | | }
  | |_- `A` defined here
...
7 |       let b = A;

GCC Version

commit-hash: c83b22a6932240194879ea7d9e783a4c0daf1b79

liamnaddell avatar Jul 27 '24 12:07 liamnaddell

Interesting issue this because in my head i thought it would just be like C:

struct test {
    int a;
    int b;
};

void test()
{
    struct test x = { .a = 1, .b = 2};
    struct test y = x;
}

Hmmm not sure if this is something we should just be doing at the code-generation level or a new lint pass.

philberty avatar Sep 20 '24 17:09 philberty

Interesting issue this because in my head i thought it would just be like C:

struct test {
    int a;
    int b;
};

void test()
{
    struct test x = { .a = 1, .b = 2};
    struct test y = x;
}

Hmmm not sure if this is something we should just be doing at the code-generation level or a new lint pass.

the example here is different than what I showed in the issue description, I think

liamnaddell avatar Sep 20 '24 17:09 liamnaddell

I think the C equivalent would be

struct test {
    int a;
    int b;
};

void test()
{
    struct test x = { .a = 1, .b = 2};
    struct test y = struct test;
}

liamnaddell avatar Sep 20 '24 17:09 liamnaddell

You should probably also get an error because a is not mutable...

dkm avatar Sep 20 '24 18:09 dkm

Here's a reproducer link:https://rust.godbolt.org/z/TKqKnMMs4

dkm avatar Sep 20 '24 18:09 dkm

I am such an idiot i misread this

philberty avatar Sep 20 '24 18:09 philberty

I am such an idiot i misread this

I made the exact same mistake when writing the code. It was only after compiling with rustc that I realized

liamnaddell avatar Sep 20 '24 18:09 liamnaddell

This is definitely not something that can be caught during parsing right? Unit structs can be instantiated using a similar pattern:

struct Y {
    y: u32,
}

struct Z;  // Unit struct. Stores no data

fn main () {
    let y = Y {y: 1};
    let z = Z;
}

GlowingScrewdriver avatar Feb 18 '25 17:02 GlowingScrewdriver

Should this type of thing be caught at the beginning of type checking, end of name resolution, or a separate phase like CfgStrip?

powerboat9 avatar Feb 18 '25 23:02 powerboat9

Same question here.

GlowingScrewdriver avatar Feb 19 '25 06:02 GlowingScrewdriver

I think this is a typechecking problem

liamnaddell avatar Feb 22 '25 01:02 liamnaddell

A is a proper type name (since it refers to struct A), but we assign a type to a variable, which should be a type error

liamnaddell avatar Feb 22 '25 01:02 liamnaddell

rustc treats this as a typechecking problem, since it emits "expected value, found struct ..."

liamnaddell avatar Feb 22 '25 01:02 liamnaddell

I'd guess that the example @GlowingScrewdriver points out is an exception, so that 'A' is treated as a value when A is a unit struct, but as a type when it's not a unit struct.

liamnaddell avatar Feb 22 '25 01:02 liamnaddell

its not a typechecking fix it needs to be caught during code-gen. Because its trying to assign a type but a type is not a value

philberty avatar Jul 10 '25 22:07 philberty