Skip to content

Following compiler suggestions for fixing errors sends me in a loop between tuple syntax and struct syntax. #85168

@dvogel

Description

@dvogel

I tried matching on the wrong error type. The compiler suggested I use a struct syntax instead of the tuple syntax. When I tried the suggested struct syntax it told me to use the same tuple syntax it had just told me not to use. I've been able to boil it down to a simpler repro case below. This is an analog of the fixed, working code:

use serde_yaml;

fn main() {
    let txt = "---\n- foo\n- bar";
    let word_list: Vec<String> = match serde_yaml::from_str(txt) {
        Ok(lst) => lst,
        Err(_) => Vec::new(),
    };
    println!("{:?}", word_list);
}

My first attempt I tried matching on the error type:

fn main() {
    let txt = "---\n- foo\n- bar";
    let word_list: Vec<String> = match serde_yaml::from_str(txt) {
        Ok(lst) => lst,
        serde_yaml::Error(_) => Vec::new(),
    };
    println!("{:?}", word_list);
}

I received this error:

error[E0532]: expected tuple struct or tuple variant, found struct `serde_yaml::Error`
  --> src/main.rs:7:9
   |
7  |         serde_yaml::Error(_) => Vec::new(),
   |         ^^^^^^^^^^^^^^^^^^^^ help: use struct pattern syntax instead: `serde_yaml::Error { 0 }`
   | 
  ::: /home/dvogel/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_yaml-0.8.17/src/error.rs:14:1
   |
14 | pub struct Error(Box<ErrorImpl>);
   | --------------------------------- `serde_yaml::Error` defined here

I'm used to the errors being quite helpful so I didn't stop to think about the code I had written and tried the suggestion:

use serde_yaml;

fn main() {
    let txt = "---\n- foo\n- bar";
    let word_list: Vec<String> = match serde_yaml::from_str(txt) {
        Ok(lst) => lst,
        serde_yaml::Error{ 0 } => Vec::new(),
    };
    println!("{:?}", word_list);
}

Which led me to this error:

error[E0769]: tuple variant `serde_yaml::Error` written as struct variant
 --> src/main.rs:7:9
  |
7 |         serde_yaml::Error{ 0 } => Vec::new(),
  |         ^^^^^^^^^^^^^^^^^^^^^^
  |
help: use the tuple variant pattern syntax instead
  |
7 |         serde_yaml::Error(_) => Vec::new(),
  |                          ^^^

Meta

This happens with the nightly version:

rustc --version --verbose
rustc 1.54.0-nightly (770792ff8 2021-05-07)
binary: rustc
commit-hash: 770792ff8d1ec542e78e77876ac936f43ffb8e05
commit-date: 2021-05-07
host: x86_64-unknown-linux-gnu
release: 1.54.0-nightly
LLVM version: 12.0.0

It does not happen with 1.52. With that version (as well as 1.47 and 1.50) I get:

error[E0532]: expected tuple struct or tuple variant, found type alias `serde_yaml::Result`
 --> src/main.rs:7:9
  |
7 |         serde_yaml::Result(_) => Vec::new(),
  |         ^^^^^^^^^^^^^^^^^^
  |
  = note: can't use a type alias as a constructor

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions