carbon-lang icon indicating copy to clipboard operation
carbon-lang copied to clipboard

Does struct field order matter for impl lookup and type structure?

Open danakj opened this issue 6 months ago • 1 comments

Summary of issue:

interface Z {
  let X:! type;
}
impl {.a: (), .b: ()} as Z where .X = i32 {}
impl {.b: (), .a: ()} as Z where .X = i64 {}

fn F() {
  let x: auto = 1 as ({.a: (), .b: ()} as Z).X;
  let y: auto = 1 as ({.b: (), .a: ()} as Z).X;
}

Is this an error because the two impls overlap? If not, is the type of x i32 and the type of y i64?

Details:

No response

Any other information that you want to share?

No response

danakj avatar May 02 '25 19:05 danakj

I want to add that structs with different fields orders but the same names are different types, but are implicitly convertible.

https://carbon.godbolt.org/z/hPdvY1e53

fn F() {
    let a: {.a: (), .b: ()} = {.b = (), .a = ()};
}

Here we see two types:

  %struct_type.a.b: type = struct_type {.a: %empty_tuple.type, .b: %empty_tuple.type} [concrete]
  %struct_type.b.a: type = struct_type {.b: %empty_tuple.type, .a: %empty_tuple.type} [concrete]

And a conversion between them:

  %.loc3_48.1: %struct_type.b.a = struct_literal (%.loc3_38, %.loc3_47)
  %struct: %struct_type.a.b = struct_value (%.loc3_48.2, %.loc3_48.3) [concrete = constants.%struct]
  %.loc3_48.4: %struct_type.a.b = converted %.loc3_48.1, %struct [concrete = constants.%struct]

danakj avatar May 06 '25 16:05 danakj

I think the "different types but convertible" model is going to be the simplest choice here. I also think it's going to be necessary in some cases -- the field order affects things like the layout of the struct, and unless we want to revisit that, we need impls for types with different field orders to be different.

zygoloid avatar Jul 03 '25 04:07 zygoloid

Let's call this decided with "different types but convertible", with rationale as provided previously.

chandlerc avatar Jul 03 '25 08:07 chandlerc

Great, thanks!

danakj avatar Jul 03 '25 15:07 danakj