This investigates the daft crate and categorizes the error cases:
- Emit code and errors (Warning error)
- Emit code only, no errors (Compile error)
- Emit errors only, no code (Error)
- Code in: enum-attributes.rs
- Generated code out
- Errors emitted
- Why it's okay to emit code: The attributes supplied cannot have any effect, so run the macro as if they weren't applied.
- Code in: struct-leaf-attributes.rs
- Errors emitted
- Generated code out
- Why it's okay to emit code: The attributes supplied cannot have any effect, so run the macro as if they weren't applied.
- Code in: union-attributes.rs
- Errors emitted
- Generated code out
- Why it's okay to emit code: The attributes supplied cannot have any effect, so run the macro as if they weren't applied.
All "warning" errors happen because the attributes cannot have any effect on the outcome. In my analysis, I found two cases where I feel we could safely emit code, but aren't:
- Code in: field-specified-multiple-times.rs
- Errors emitted
- Generated code out: Empty
- Why I think it's okay to emit code here: This code has the same attribute repeated several times. This could happen if someone deleted a field but forgot to delete it's attribute. It should be cleaned up, but since all signals point to the same intention we should be able to emit generated code, but are not.
- Code in: struct-specified-multiple-times.rs
- Errors emitted
- Generated code out: Empty
- Why I think it's okay to emit code here: This code has the same problem as
field-specified-multiple-times.rs
but the duplicate attribute is on the container (struct) rather than the field. The intent is clear, code generation should be possible
- Code in: field-attribute-with-value.rs
- Errors emitted
- Generated code out: None
- Why no code was emitted: An invalid format was provided for attributes on the struct. Fixing this problem may change the generated output so emit nothing. Force the developer to fix the syntax error.
- Code in: field-leaf-and-ignore.rs
- Errors emitted
- Generated code out: None
- Why no code was emitted: Attributes are syntactically valid but conflict with each other. If the developer picks one or the other it will change the generated output. Emit nothing. Force the developer to choose.
- Code in: field-unknown-attribute.rs
- Errors emitted
- Generated code out: None
- Why no code was emitted: An attribute name was supplied that isn't supported via daft. The intent is unclear. Treat this like a syntax error. Do not generate code.
- Code in: struct-attribute-with-value.rs
- Errors emitted
- Generated code out: None
- Why no code was emitted: Cannot parse attributes, treat as a syntax error
- Code in: field-unknown-attribute.rs
- Errors emitted
- Generated code out: None
- Why no code was emitted: An
ignore
attribute is used on a struct (container) which is not supported. Treat it as a syntax error since we don't know what they wanted.
- Code in: struct-field-not-diffable.rs
- Errors emitted
- Generated code out
- Why it's okay to emit code: No error is found at macro time, the error comes from the compiler because of the emitted code, not despite it. The macro cannot reflect whether a given struct has an implementation or not. Therefore, it must emit the code to let the compiler issue a warning.
This failure mode is fairly normal for a macro as we don't have enough reflective power to detect the error. While reflection tools in a language like Ruby might allow us to query the capabilities of an object duck.respond_to?(:quack)
, there's currently no way to ask Rust "does this struct implement this trait?" So there's nothing else the macro could do other than emit code and let the compiler produce a (hopefully) helpful error message.
Please don't leave comments here. I won't be notified about them. Message me on mastodon please.