A way to guarantee to the compiler that a type has a certain field

Currently in Rust, there is no way to guarantee to the compiler that something for sure has a certain field. For example, if you are using an enum that has multiple fields, and all of those fields have the exact same name, type and purpose. I want a "semi-struct" of sorts (or maybe just a struct) that can guarantee that all variants inside of an enum have a certain field. Maybe this could also see extended use in traits or functions, to guarantee that XYZ field exists.

I have no idea how the syntax should (ideally) be structured, but here is a proposal that I have in Rust pseudocode.

The drawbacks that I see for this are in the pseudocode's comments.

// 'strict' will be important later
strict field FooField {
  x: usize,
  y: usize
}

field BarField {
  x: usize,
  y: usize
}

// The 'strict' specifier now comes into play here. Now you can automatically implement a new
// function for types that don't implement it and also have the FooField field.

trait FooTrait {
  // I think the dyn keyword should be required
  // for non-strict fields like BarField. 
  
  // You also shouldn't be able to initiate a type
  // from Output unless it used a "strict" field.
  type Output: FooField;
  fn new(x: usize, y: usize) -> Output {
    Output {
      x,
      y
    }
  }
}
// Implementing MULTIPLE fields on a tuple would also be problematic
// because it uses numbers to access values, as opposed to their names.

field BarTuple(x: usize, y: usize);

// Using anonymous parameters for the declaration above is probably 
// just a bad idea because it makes the purpose of these values 
// less clear.

enum FooEnum with FooField {
    FooVariant {
     // Shorthand, so you don't need to specify types.
     // Also increases clarity as to which types
     // come from the variant and which from the current type

     // Do note that, due to the strict keyword, this doesn't compile!
      x,
      y,
      // This throws a compiler error because 'strict' was specified. That means
      // that the enum cannot contain any additional fields.
      s: usize
   }
   // Fails, no X or Y fields
   BarVariant,
   NoIdeaVariant {
      // Success!
      x,
      y
   }
}

// All variants must have at least BarField's components,
// but can also add their own things
enum BarEnum with BarField {
   // Valid
   Pos3D {
     x,
     y,
     z: usize
   }
  // Valid
  Pos2D {
    x, y
  }
  // Invalid
  Pos1D {
    x
  }

}

As always, I greatly appreciate criticism.

1 Like

Potentially relevant:

1 Like

See also:

2 Likes

@scottmcm , @quinedot This is almost exactly what I'm looking for! It's just that, from my initial glance and skim-through, these have not been updated in a very long while. :frowning:

Indirectly related: this section in RFC2584 rfcs/0000-structural-records.md at rfc/structural-records · Centril/rfcs (github.com)

1 Like