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