oxidecomputer / typify

compiler from JSON Schema into idiomatic Rust types
Apache License 2.0
423 stars 58 forks source link

Objects fields named Result generate code that (generally) won't compile #568

Open colmanhumphrey opened 5 months ago

colmanhumphrey commented 5 months ago

Having a Result definition seems to create code that won't compile, if std::result::Result is needed.

Reproduction

A simplified schema that shows the issue (note: if you don't have the enum, or something that needs a result, it won't give the error):

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Test",
  "type": "object",
  "properties": {
    "results": {
      "$ref": "#/definitions/MultipleResult"
    }
  },
  "definitions": {
    "MultipleResult": {
      "type": "object",
      "properties": {
        "results": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/Result"
          }
        }
      }
    },
    "Result": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        }
      }
    },
    "SomeEnum": {
      "type": "string",
      "description": "",
      "enum": [
        "Arm1",
        "Arm2",
        "Arm3"
      ]
    }
  }
}
Gives: ```rust error[E0107]: struct takes 0 generic arguments but 2 generic arguments were supplied --> src/lib.rs:136:33 | 136 | fn try_from(value: &str) -> Result { | ^^^^^^------------------------------------ help: remove these generics | | | expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> src/lib.rs:78:12 | 78 | pub struct Result { | ^^^^^^ error[E0107]: struct takes 0 generic arguments but 2 generic arguments were supplied --> src/lib.rs:142:36 | 142 | fn try_from(value: &String) -> Result { | ^^^^^^------------------------------------ help: remove these generics | | | expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> src/lib.rs:78:12 | 78 | pub struct Result { | ^^^^^^ error[E0107]: struct takes 0 generic arguments but 2 generic arguments were supplied --> src/lib.rs:125:33 | 125 | fn from_str(value: &str) -> Result { | ^^^^^^------------------------------------ help: remove these generics | | | expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> src/lib.rs:78:12 | 78 | pub struct Result { | ^^^^^^ error[E0053]: method `from_str` has an incompatible type for trait --> src/lib.rs:125:33 | 125 | fn from_str(value: &str) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | expected `Result`, found `Result` | help: change the output type to match the trait: `std::result::Result` | = note: expected signature `fn(&_) -> std::result::Result` found signature `fn(&_) -> Result` error[E0053]: method `try_from` has an incompatible type for trait --> src/lib.rs:136:33 | 136 | fn try_from(value: &str) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | expected `Result`, found `Result` | help: change the output type to match the trait: `std::result::Result` | = note: expected signature `fn(&_) -> std::result::Result` found signature `fn(&_) -> Result` error[E0053]: method `try_from` has an incompatible type for trait --> src/lib.rs:142:36 | 142 | fn try_from(value: &String) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | expected `Result`, found `Result` | help: change the output type to match the trait: `std::result::Result` | = note: expected signature `fn(&std::string::String) -> std::result::Result` found signature `fn(&std::string::String) -> Result` error[E0107]: struct takes 0 generic arguments but 2 generic arguments were supplied --> src/lib.rs:148:35 | 148 | fn try_from(value: String) -> Result { | ^^^^^^------------------------------------ help: remove these generics | | | expected 0 generic arguments | note: struct defined here, with 0 generic parameters --> src/lib.rs:78:12 | 78 | pub struct Result { | ^^^^^^ error[E0053]: method `try_from` has an incompatible type for trait --> src/lib.rs:148:35 | 148 | fn try_from(value: String) -> Result { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | | expected `Result`, found `Result` | help: change the output type to match the trait: `std::result::Result` | = note: expected signature `fn(std::string::String) -> std::result::Result` found signature `fn(std::string::String) -> Result` error[E0308]: mismatched types --> src/lib.rs:127:23 | 125 | fn from_str(value: &str) -> Result { | ------------------------------------------ expected `Result` because of return type 126 | match value { 127 | "Arm1" => Ok(Self::Arm1), | ^^^^^^^^^^^^^^ expected `Result`, found `Result` | = note: `std::result::Result` and `Result` have similar names, but are actually distinct types note: `std::result::Result` is defined in crate `core` --> /Users/colmanhumphrey/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:502:1 | 502 | pub enum Result { | ^^^^^^^^^^^^^^^^^^^^^ note: `Result` is defined in the current crate --> src/lib.rs:78:1 | 78 | pub struct Result { | ^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> src/lib.rs:137:9 | 136 | fn try_from(value: &str) -> Result { | ------------------------------------------ expected `Result` because of return type 137 | value.parse() | ^^^^^^^^^^^^^ expected `Result`, found `Result<_, _>` | = note: `std::result::Result<_, _>` and `Result` have similar names, but are actually distinct types note: `std::result::Result<_, _>` is defined in crate `core` --> /Users/colmanhumphrey/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:502:1 | 502 | pub enum Result { | ^^^^^^^^^^^^^^^^^^^^^ note: `Result` is defined in the current crate --> src/lib.rs:78:1 | 78 | pub struct Result { | ^^^^^^^^^^^^^^^^^ help: consider using `Result::expect` to unwrap the `std::result::Result<_, _>` value, panicking if the value is a `Result::Err` | 137 | value.parse().expect("REASON") | +++++++++++++++++ error[E0308]: mismatched types --> src/lib.rs:143:9 | 142 | fn try_from(value: &String) -> Result { | ------------------------------------------ expected `Result` because of return type 143 | value.parse() | ^^^^^^^^^^^^^ expected `Result`, found `Result<_, _>` | = note: `std::result::Result<_, _>` and `Result` have similar names, but are actually distinct types note: `std::result::Result<_, _>` is defined in crate `core` --> /Users/colmanhumphrey/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:502:1 | 502 | pub enum Result { | ^^^^^^^^^^^^^^^^^^^^^ note: `Result` is defined in the current crate --> src/lib.rs:78:1 | 78 | pub struct Result { | ^^^^^^^^^^^^^^^^^ help: consider using `Result::expect` to unwrap the `std::result::Result<_, _>` value, panicking if the value is a `Result::Err` | 143 | value.parse().expect("REASON") | +++++++++++++++++ error[E0308]: mismatched types --> src/lib.rs:149:9 | 148 | fn try_from(value: String) -> Result { | ------------------------------------------ expected `Result` because of return type 149 | value.parse() | ^^^^^^^^^^^^^ expected `Result`, found `Result<_, _>` | = note: `std::result::Result<_, _>` and `Result` have similar names, but are actually distinct types note: `std::result::Result<_, _>` is defined in crate `core` --> /Users/colmanhumphrey/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:502:1 | 502 | pub enum Result { | ^^^^^^^^^^^^^^^^^^^^^ note: `Result` is defined in the current crate --> src/lib.rs:78:1 | 78 | pub struct Result { | ^^^^^^^^^^^^^^^^^ help: consider using `Result::expect` to unwrap the `std::result::Result<_, _>` value, panicking if the value is a `Result::Err` | 149 | value.parse().expect("REASON") | +++++++++++++++++ Some errors have detailed explanations: E0053, E0107, E0308. For more information about an error, try `rustc --explain E0053`. error: could not compile `inspection-schema` (lib) due to 12 previous errors ```

Solve

I think an explicit Result, like https://github.com/oxidecomputer/typify/pull/458, should hopefully solve it.

(meanwhile, I will probably change my field name...)

Thanks!

ahl commented 5 months ago

Thanks for the bug report. It sounds like we should fully qualify our use of std::result::Result to avoid ambiguity.