#[macro_use]
extern crate derive_new;
-#[cfg(test)]
#[macro_use]
extern crate lazy_static;
#[macro_use]
use std::path::PathBuf;
use std::rc::Rc;
-use failure::Fail;
use ignore;
-use syntax::{ast, parse::DirectoryOwnership};
+use rustc_ast::ast;
+use rustc_span::symbol;
+use thiserror::Error;
use crate::comment::LineClasses;
use crate::emitter::Emitter;
use crate::formatting::{FormatErrorMap, FormattingError, ReportedErrors, SourceFile};
use crate::issues::Issue;
+use crate::modules::ModuleResolutionError;
use crate::shape::Indent;
+use crate::syntux::parser::DirectoryOwnership;
use crate::utils::indent_next_line;
pub use crate::config::{
#[macro_use]
mod utils;
-#[macro_use]
-mod release_channel;
-
mod attr;
mod chains;
mod closures;
mod comment;
pub(crate) mod config;
+mod coverage;
mod emitter;
mod expr;
mod format_report_formatter;
mod overflow;
mod pairs;
mod patterns;
+mod release_channel;
mod reorder;
mod rewrite;
pub(crate) mod rustfmt_diff;
mod shape;
+mod skip;
pub(crate) mod source_file;
pub(crate) mod source_map;
mod spanned;
mod stmt;
mod string;
+mod syntux;
#[cfg(test)]
mod test;
mod types;
/// The various errors that can occur during formatting. Note that not all of
/// these can currently be propagated to clients.
-#[derive(Fail, Debug)]
+#[derive(Error, Debug)]
pub enum ErrorKind {
/// Line has exceeded character limit (found, maximum).
- #[fail(
- display = "line formatted, but exceeded maximum width \
- (maximum: {} (see `max_width` option), found: {})",
- _1, _0
+ #[error(
+ "line formatted, but exceeded maximum width \
+ (maximum: {1} (see `max_width` option), found: {0})"
)]
LineOverflow(usize, usize),
/// Line ends in whitespace.
- #[fail(display = "left behind trailing whitespace")]
+ #[error("left behind trailing whitespace")]
TrailingWhitespace,
/// TODO or FIXME item without an issue number.
- #[fail(display = "found {}", _0)]
+ #[error("found {0}")]
BadIssue(Issue),
/// License check has failed.
- #[fail(display = "license check failed")]
+ #[error("license check failed")]
LicenseCheck,
/// Used deprecated skip attribute.
- #[fail(display = "`rustfmt_skip` is deprecated; use `rustfmt::skip`")]
+ #[error("`rustfmt_skip` is deprecated; use `rustfmt::skip`")]
DeprecatedAttr,
/// Used a rustfmt:: attribute other than skip or skip::macros.
- #[fail(display = "invalid attribute")]
+ #[error("invalid attribute")]
BadAttr,
/// An io error during reading or writing.
- #[fail(display = "io error: {}", _0)]
+ #[error("io error: {0}")]
IoError(io::Error),
+ /// Error during module resolution.
+ #[error("{0}")]
+ ModuleResolutionError(#[from] ModuleResolutionError),
/// Parse error occurred when parsing the input.
- #[fail(display = "parse error")]
+ #[error("parse error")]
ParseError,
/// The user mandated a version and the current version of Rustfmt does not
/// satisfy that requirement.
- #[fail(display = "version mismatch")]
+ #[error("version mismatch")]
VersionMismatch,
/// If we had formatted the given node, then we would have lost a comment.
- #[fail(display = "not formatted because a comment would be lost")]
+ #[error("not formatted because a comment would be lost")]
LostComment,
/// Invalid glob pattern in `ignore` configuration option.
- #[fail(display = "Invalid glob pattern found in ignore list: {}", _0)]
+ #[error("Invalid glob pattern found in ignore list: {0}")]
InvalidGlobPattern(ignore::Error),
}
}
}
-#[deprecated(note = "Use FormatReportFormatter instead")]
+/// Deprecated - Use FormatReportFormatter instead
+// https://github.com/rust-lang/rust/issues/78625
+// https://github.com/rust-lang/rust/issues/39935
impl fmt::Display for FormatReport {
// Prints all the formatting errors.
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
/// Format the given snippet. The snippet is expected to be *complete* code.
/// When we cannot parse the given snippet, this function returns `None`.
-fn format_snippet(snippet: &str, config: &Config) -> Option<FormattedSnippet> {
+fn format_snippet(snippet: &str, config: &Config, is_macro_def: bool) -> Option<FormattedSnippet> {
let mut config = config.clone();
panic::catch_unwind(|| {
let mut out: Vec<u8> = Vec::with_capacity(snippet.len() * 2);
let (formatting_error, result) = {
let input = Input::Text(snippet.into());
let mut session = Session::new(config, Some(&mut out));
- let result = session.format(input);
+ let result = session.format_input_inner(input, is_macro_def);
(
session.errors.has_macro_format_failure
|| session.out.as_ref().unwrap().is_empty() && !snippet.is_empty()
/// The code block may be incomplete (i.e., parser may be unable to parse it).
/// To avoid panic in parser, we wrap the code block with a dummy function.
/// The returned code block does **not** end with newline.
-fn format_code_block(code_snippet: &str, config: &Config) -> Option<FormattedSnippet> {
+fn format_code_block(
+ code_snippet: &str,
+ config: &Config,
+ is_macro_def: bool,
+) -> Option<FormattedSnippet> {
const FN_MAIN_PREFIX: &str = "fn main() {\n";
fn enclose_in_main_block(s: &str, config: &Config) -> String {
config_with_unix_newline
.set()
.newline_style(NewlineStyle::Unix);
- let mut formatted = format_snippet(&snippet, &config_with_unix_newline)?;
+ let mut formatted = format_snippet(&snippet, &config_with_unix_newline, is_macro_def)?;
// Remove wrapping main block
formatted.unwrap_code_block();
/// The main entry point for Rustfmt. Formats the given input according to the
/// given config. `out` is only necessary if required by the configuration.
pub fn format(&mut self, input: Input) -> Result<FormatReport, ErrorKind> {
- self.format_input_inner(input)
+ self.format_input_inner(input, false)
}
pub fn override_config<F, U>(&mut self, mut config: Config, f: F) -> U
EmitMode::Files if config.make_backup() => {
Box::new(emitter::FilesWithBackupEmitter::default())
}
- EmitMode::Files => Box::new(emitter::FilesEmitter::default()),
+ EmitMode::Files => Box::new(emitter::FilesEmitter::new(
+ config.print_misformatted_file_names(),
+ )),
EmitMode::Stdout | EmitMode::Coverage => {
Box::new(emitter::StdoutEmitter::new(config.verbose()))
}
+ EmitMode::Json => Box::new(emitter::JsonEmitter::default()),
EmitMode::ModifiedLines => Box::new(emitter::ModifiedLinesEmitter::default()),
EmitMode::Checkstyle => Box::new(emitter::CheckstyleEmitter::default()),
EmitMode::Diff => Box::new(emitter::DiffEmitter::new(config.clone())),
}
impl Input {
- fn is_text(&self) -> bool {
- match *self {
- Input::File(_) => false,
- Input::Text(_) => true,
- }
- }
-
fn file_name(&self) -> FileName {
match *self {
Input::File(ref file) => FileName::Real(file.clone()),
let file_stem = file.file_stem()?;
if file.parent()?.to_path_buf().join(file_stem).is_dir() {
Some(DirectoryOwnership::Owned {
- relative: file_stem.to_str().map(ast::Ident::from_str),
+ relative: file_stem.to_str().map(symbol::Ident::from_str),
})
} else {
None
// `format_snippet()` and `format_code_block()` should not panic
// even when we cannot parse the given snippet.
let snippet = "let";
- assert!(format_snippet(snippet, &Config::default()).is_none());
- assert!(format_code_block(snippet, &Config::default()).is_none());
+ assert!(format_snippet(snippet, &Config::default(), false).is_none());
+ assert!(format_code_block(snippet, &Config::default(), false).is_none());
}
fn test_format_inner<F>(formatter: F, input: &str, expected: &str) -> bool
where
- F: Fn(&str, &Config) -> Option<FormattedSnippet>,
+ F: Fn(&str, &Config, bool) -> Option<FormattedSnippet>,
{
- let output = formatter(input, &Config::default());
+ let output = formatter(input, &Config::default(), false);
output.is_some() && output.unwrap().snippet == expected
}
fn test_format_code_block_fail() {
#[rustfmt::skip]
let code_block = "this_line_is_100_characters_long_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx(x, y, z);";
- assert!(format_code_block(code_block, &Config::default()).is_none());
+ assert!(format_code_block(code_block, &Config::default(), false).is_none());
}
#[test]