Source code
Revision control
Copy as Markdown
Other Tools
#![allow(clippy::iter_cloned_collect, clippy::uninlined_format_args)]
use core::fmt::Display;
use thiserror::Error;
// Some of the elaborate cases from the rcc codebase, which is a C compiler in
#[derive(Error, Debug)]
pub enum CompilerError {
#[error("cannot shift {} by {maximum} or more bits (got {current})", if *.is_left { "left" } else { "right" })]
TooManyShiftBits {
is_left: bool,
maximum: u64,
current: u64,
},
#[error("#error {}", (.0).iter().copied().collect::<Vec<_>>().join(" "))]
User(Vec<&'static str>),
#[error("overflow while parsing {}integer literal",
if let Some(signed) = .is_signed {
if *signed { "signed "} else { "unsigned "}
} else {
""
}
)]
IntegerOverflow { is_signed: Option<bool> },
#[error("overflow while parsing {}integer literal", match .is_signed {
Some(true) => "signed ",
Some(false) => "unsigned ",
None => "",
})]
IntegerOverflow2 { is_signed: Option<bool> },
}
// Examples drawn from Rustup.
#[derive(Error, Debug)]
pub enum RustupError {
#[error(
"toolchain '{name}' does not contain component {component}{}",
.suggestion
.as_ref()
.map_or_else(String::new, |s| format!("; did you mean '{}'?", s)),
)]
UnknownComponent {
name: String,
component: String,
suggestion: Option<String>,
},
}
fn assert<T: Display>(expected: &str, value: T) {
assert_eq!(expected, value.to_string());
}
#[test]
fn test_rcc() {
assert(
"cannot shift left by 32 or more bits (got 50)",
CompilerError::TooManyShiftBits {
is_left: true,
maximum: 32,
current: 50,
},
);
assert("#error A B C", CompilerError::User(vec!["A", "B", "C"]));
assert(
"overflow while parsing signed integer literal",
CompilerError::IntegerOverflow {
is_signed: Some(true),
},
);
}
#[test]
fn test_rustup() {
assert(
"toolchain 'nightly' does not contain component clipy; did you mean 'clippy'?",
RustupError::UnknownComponent {
name: "nightly".to_owned(),
component: "clipy".to_owned(),
suggestion: Some("clippy".to_owned()),
},
);
}