1 #![allow( 2 clippy::iter_cloned_collect, 3 clippy::option_if_let_else, 4 clippy::uninlined_format_args 5 )] 6 7 use std::fmt::Display; 8 use thiserror::Error; 9 10 // Some of the elaborate cases from the rcc codebase, which is a C compiler in 11 // Rust. https://github.com/jyn514/rcc/blob/0.8.0/src/data/error.rs 12 #[derive(Error, Debug)] 13 pub enum CompilerError { 14 #[error("cannot shift {} by {maximum} or more bits (got {current})", if *.is_left { "left" } else { "right" })] 15 TooManyShiftBits { 16 is_left: bool, 17 maximum: u64, 18 current: u64, 19 }, 20 21 #[error("#error {}", (.0).iter().copied().collect::<Vec<_>>().join(" "))] 22 User(Vec<&'static str>), 23 24 #[error("overflow while parsing {}integer literal", 25 if let Some(signed) = .is_signed { 26 if *signed { "signed "} else { "unsigned "} 27 } else { 28 "" 29 } 30 )] 31 IntegerOverflow { is_signed: Option<bool> }, 32 33 #[error("overflow while parsing {}integer literal", match .is_signed { 34 Some(true) => "signed ", 35 Some(false) => "unsigned ", 36 None => "", 37 })] 38 IntegerOverflow2 { is_signed: Option<bool> }, 39 } 40 41 // Examples drawn from Rustup. 42 #[derive(Error, Debug)] 43 pub enum RustupError { 44 #[error( 45 "toolchain '{name}' does not contain component {component}{}", 46 .suggestion 47 .as_ref() 48 .map_or_else(String::new, |s| format!("; did you mean '{}'?", s)), 49 )] 50 UnknownComponent { 51 name: String, 52 component: String, 53 suggestion: Option<String>, 54 }, 55 } 56 57 fn assert<T: Display>(expected: &str, value: T) { 58 assert_eq!(expected, value.to_string()); 59 } 60 61 #[test] 62 fn test_rcc() { 63 assert( 64 "cannot shift left by 32 or more bits (got 50)", 65 CompilerError::TooManyShiftBits { 66 is_left: true, 67 maximum: 32, 68 current: 50, 69 }, 70 ); 71 72 assert("#error A B C", CompilerError::User(vec!["A", "B", "C"])); 73 74 assert( 75 "overflow while parsing signed integer literal", 76 CompilerError::IntegerOverflow { 77 is_signed: Some(true), 78 }, 79 ); 80 } 81 82 #[test] 83 fn test_rustup() { 84 assert( 85 "toolchain 'nightly' does not contain component clipy; did you mean 'clippy'?", 86 RustupError::UnknownComponent { 87 name: "nightly".to_owned(), 88 component: "clipy".to_owned(), 89 suggestion: Some("clippy".to_owned()), 90 }, 91 ); 92 } 93