diff --git a/rust-toolchain b/rust-toolchain index 7cd537279d2..348664bc168 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-12-02" +channel = "nightly-2025-01-02" components = ["llvm-tools", "rustc-dev"] diff --git a/src/bin/main.rs b/src/bin/main.rs index fe24276311e..b72bad873d9 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -135,6 +135,12 @@ fn make_opts() -> Options { "Rust edition to use", "[2015|2018|2021|2024]", ); + opts.optopt( + "", + "style-edition", + "The edition of the Style Guide (unstable).", + "[2015|2018|2021|2024]", + ); opts.optopt( "", "color", @@ -186,12 +192,6 @@ fn make_opts() -> Options { "skip-children", "Don't reformat child modules (unstable).", ); - opts.optopt( - "", - "style-edition", - "The edition of the Style Guide (unstable).", - "[2015|2018|2021|2024]", - ); } opts.optflag("v", "verbose", "Print verbose output"); @@ -568,10 +568,6 @@ impl GetOptsOptions { if let Some(ref file_lines) = matches.opt_str("file-lines") { options.file_lines = file_lines.parse()?; } - if let Some(ref edition_str) = matches.opt_str("style-edition") { - options.style_edition = - Some(style_edition_from_style_edition_str(edition_str)?); - } } else { let mut unstable_options = vec![]; if matches.opt_present("skip-children") { @@ -583,9 +579,6 @@ impl GetOptsOptions { if matches.opt_present("file-lines") { unstable_options.push("`--file-lines`"); } - if matches.opt_present("style-edition") { - unstable_options.push("`--style-edition`"); - } if !unstable_options.is_empty() { let s = if unstable_options.len() == 1 { "" } else { "s" }; return Err(format_err!( @@ -635,6 +628,10 @@ impl GetOptsOptions { options.edition = Some(edition_from_edition_str(edition_str)?); } + if let Some(ref edition_str) = matches.opt_str("style-edition") { + options.style_edition = Some(style_edition_from_style_edition_str(edition_str)?); + } + if matches.opt_present("backup") { options.backup = true; } diff --git a/src/config/mod.rs b/src/config/mod.rs index ea257c0a8ba..7355adc9f9d 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -29,7 +29,7 @@ pub(crate) mod style_edition; // This macro defines configuration options used in rustfmt. Each option // is defined as follows: // -// `name: value type, default value, is stable, description;` +// `name: value type, is stable, description;` create_config! { // Fundamental stuff max_width: MaxWidth, true, "Maximum width of each line"; @@ -149,7 +149,7 @@ create_config! { blank_lines_lower_bound: BlankLinesLowerBound, false, "Minimum number of blank lines which must be put between items"; edition: EditionConfig, true, "The edition of the parser (RFC 2052)"; - style_edition: StyleEditionConfig, false, "The edition of the Style Guide (RFC 3338)"; + style_edition: StyleEditionConfig, true, "The edition of the Style Guide (RFC 3338)"; version: VersionConfig, false, "Version of formatting rules"; inline_attribute_width: InlineAttributeWidth, false, "Write an item and its attribute on the same line \ diff --git a/src/config/options.rs b/src/config/options.rs index 14ffdd21707..b9b4713046c 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -511,7 +511,6 @@ pub enum StyleEdition { Edition2021, #[value = "2024"] #[doc_hint = "2024"] - #[unstable_variant] /// [Edition 2024](). Edition2024, #[value = "2027"] diff --git a/src/expr.rs b/src/expr.rs index 0751d65a438..8031ab68290 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -421,7 +421,8 @@ pub(crate) fn format_expr( ast::ExprKind::FormatArgs(..) | ast::ExprKind::Type(..) | ast::ExprKind::IncludedBytes(..) - | ast::ExprKind::OffsetOf(..) => { + | ast::ExprKind::OffsetOf(..) + | ast::ExprKind::UnsafeBinderCast(..) => { // These don't normally occur in the AST because macros aren't expanded. However, // rustfmt tries to parse macro arguments when formatting macros, so it's not totally // impossible for rustfmt to come across one of these nodes when formatting a file. diff --git a/src/items.rs b/src/items.rs index 90364ed603a..901ad44edab 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1930,6 +1930,11 @@ pub(crate) fn rewrite_struct_field( shape: Shape, lhs_max_width: usize, ) -> RewriteResult { + // FIXME(default_field_values): Implement formatting. + if field.default.is_some() { + return Err(RewriteError::Unknown); + } + if contains_skip(&field.attrs) { return Ok(context.snippet(field.span()).to_owned()); } @@ -3581,7 +3586,7 @@ pub(crate) fn rewrite_extern_crate( pub(crate) fn is_mod_decl(item: &ast::Item) -> bool { !matches!( item.kind, - ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _)) + ast::ItemKind::Mod(_, ast::ModKind::Loaded(_, ast::Inline::Yes, _, _)) ) } diff --git a/src/macros.rs b/src/macros.rs index 4acc10edb56..1049fab1ebd 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use std::panic::{AssertUnwindSafe, catch_unwind}; use rustc_ast::token::{BinOpToken, Delimiter, Token, TokenKind}; -use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree}; +use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree}; use rustc_ast::{ast, ptr}; use rustc_ast_pretty::pprust; use rustc_span::{ @@ -441,7 +441,7 @@ pub(crate) fn rewrite_macro_def( } let ts = def.body.tokens.clone(); - let mut parser = MacroParser::new(ts.trees()); + let mut parser = MacroParser::new(ts.iter()); let parsed_def = match parser.parse() { Some(def) => def, None => return snippet, @@ -792,7 +792,7 @@ impl MacroArgParser { self.buf.clear(); } - fn add_meta_variable(&mut self, iter: &mut RefTokenTreeCursor<'_>) -> Option<()> { + fn add_meta_variable(&mut self, iter: &mut TokenStreamIter<'_>) -> Option<()> { match iter.next() { Some(&TokenTree::Token( Token { @@ -824,7 +824,7 @@ impl MacroArgParser { &mut self, inner: Vec, delim: Delimiter, - iter: &mut RefTokenTreeCursor<'_>, + iter: &mut TokenStreamIter<'_>, ) -> Option<()> { let mut buffer = String::new(); let mut first = true; @@ -924,7 +924,7 @@ impl MacroArgParser { /// Returns a collection of parsed macro def's arguments. fn parse(mut self, tokens: TokenStream) -> Option> { - let mut iter = tokens.trees(); + let mut iter = tokens.iter(); while let Some(tok) = iter.next() { match tok { @@ -1061,7 +1061,7 @@ fn format_macro_args( } fn span_for_token_stream(token_stream: &TokenStream) -> Option { - token_stream.trees().next().map(|tt| tt.span()) + token_stream.iter().next().map(|tt| tt.span()) } // We should insert a space if the next token is a: @@ -1177,18 +1177,18 @@ pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> D // A very simple parser that just parses a macros 2.0 definition into its branches. // Currently we do not attempt to parse any further than that. struct MacroParser<'a> { - toks: RefTokenTreeCursor<'a>, + iter: TokenStreamIter<'a>, } impl<'a> MacroParser<'a> { - const fn new(toks: RefTokenTreeCursor<'a>) -> Self { - Self { toks } + const fn new(iter: TokenStreamIter<'a>) -> Self { + Self { iter } } // (`(` ... `)` `=>` `{` ... `}`)* fn parse(&mut self) -> Option { let mut branches = vec![]; - while self.toks.look_ahead(1).is_some() { + while self.iter.peek().is_some() { branches.push(self.parse_branch()?); } @@ -1197,13 +1197,13 @@ impl<'a> MacroParser<'a> { // `(` ... `)` `=>` `{` ... `}` fn parse_branch(&mut self) -> Option { - let tok = self.toks.next()?; + let tok = self.iter.next()?; let (lo, args_paren_kind) = match tok { TokenTree::Token(..) => return None, &TokenTree::Delimited(delimited_span, _, d, _) => (delimited_span.open.lo(), d), }; let args = TokenStream::new(vec![tok.clone()]); - match self.toks.next()? { + match self.iter.next()? { TokenTree::Token( Token { kind: TokenKind::FatArrow, @@ -1213,7 +1213,7 @@ impl<'a> MacroParser<'a> { ) => {} _ => return None, } - let (mut hi, body, whole_body) = match self.toks.next()? { + let (mut hi, body, whole_body) = match self.iter.next()? { TokenTree::Token(..) => return None, TokenTree::Delimited(delimited_span, ..) => { let data = delimited_span.entire().data(); @@ -1235,10 +1235,10 @@ impl<'a> MacroParser<'a> { span, }, _, - )) = self.toks.look_ahead(0) + )) = self.iter.peek() { hi = span.hi(); - self.toks.next(); + self.iter.next(); } Some(MacroBranch { span: mk_sp(lo, hi), diff --git a/src/modules.rs b/src/modules.rs index 493b04f16c6..a40ee7f66a9 100644 --- a/src/modules.rs +++ b/src/modules.rs @@ -316,12 +316,11 @@ impl<'ast, 'psess, 'c> ModResolver<'ast, 'psess> { self.directory = directory; } match (sub_mod.ast_mod_kind, sub_mod.items) { - (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => { + (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _, _))), _) => { self.visit_mod_from_ast(items) } - (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _))), _) | (_, Cow::Owned(items)) => { - self.visit_mod_outside_ast(items) - } + (Some(Cow::Owned(ast::ModKind::Loaded(items, _, _, _))), _) + | (_, Cow::Owned(items)) => self.visit_mod_outside_ast(items), (_, _) => Ok(()), } } diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index ec771f96a3f..0b7b6c4d361 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -2,6 +2,7 @@ use std::panic::{AssertUnwindSafe, catch_unwind}; use rustc_ast::ast; use rustc_ast::token::{Delimiter, TokenKind}; +use rustc_parse::exp; use rustc_parse::parser::ForceCollect; use rustc_span::symbol::kw; @@ -31,7 +32,7 @@ fn parse_cfg_if_inner<'a>( while parser.token.kind != TokenKind::Eof { if process_if_cfg { - if !parser.eat_keyword(kw::If) { + if !parser.eat_keyword(exp!(If)) { return Err("Expected `if`"); } @@ -55,7 +56,7 @@ fn parse_cfg_if_inner<'a>( })?; } - if !parser.eat(&TokenKind::OpenDelim(Delimiter::Brace)) { + if !parser.eat(exp!(OpenBrace)) { return Err("Expected an opening brace"); } @@ -78,15 +79,15 @@ fn parse_cfg_if_inner<'a>( } } - if !parser.eat(&TokenKind::CloseDelim(Delimiter::Brace)) { + if !parser.eat(exp!(CloseBrace)) { return Err("Expected a closing brace"); } - if parser.eat(&TokenKind::Eof) { + if parser.eat(exp!(Eof)) { break; } - if !parser.eat_keyword(kw::Else) { + if !parser.eat_keyword(exp!(Else)) { return Err("Expected `else`"); } diff --git a/src/parse/macros/lazy_static.rs b/src/parse/macros/lazy_static.rs index b6de5f8691c..cbe81004e22 100644 --- a/src/parse/macros/lazy_static.rs +++ b/src/parse/macros/lazy_static.rs @@ -1,8 +1,9 @@ use rustc_ast::ast; use rustc_ast::ptr::P; -use rustc_ast::token::TokenKind; +use rustc_ast::token; use rustc_ast::tokenstream::TokenStream; -use rustc_span::symbol::{self, kw}; +use rustc_parse::exp; +use rustc_span::symbol; use crate::rewrite::RewriteContext; @@ -31,19 +32,19 @@ pub(crate) fn parse_lazy_static( } } } - while parser.token.kind != TokenKind::Eof { + while parser.token.kind != token::Eof { // Parse a `lazy_static!` item. // FIXME: These `eat_*` calls should be converted to `parse_or` to avoid // silently formatting malformed lazy-statics. let vis = parse_or!(parse_visibility, rustc_parse::parser::FollowedByType::No); - let _ = parser.eat_keyword(kw::Static); - let _ = parser.eat_keyword(kw::Ref); + let _ = parser.eat_keyword(exp!(Static)); + let _ = parser.eat_keyword(exp!(Ref)); let id = parse_or!(parse_ident); - let _ = parser.eat(&TokenKind::Colon); + let _ = parser.eat(exp!(Colon)); let ty = parse_or!(parse_ty); - let _ = parser.eat(&TokenKind::Eq); + let _ = parser.eat(exp!(Eq)); let expr = parse_or!(parse_expr); - let _ = parser.eat(&TokenKind::Semi); + let _ = parser.eat(exp!(Semi)); result.push((vis, id, ty, expr)); } diff --git a/src/parse/macros/mod.rs b/src/parse/macros/mod.rs index 7271e73db8d..680a35f7e03 100644 --- a/src/parse/macros/mod.rs +++ b/src/parse/macros/mod.rs @@ -4,8 +4,7 @@ use rustc_ast::{ast, ptr}; use rustc_parse::MACRO_ARGUMENTS; use rustc_parse::parser::{ForceCollect, Parser, Recovery}; use rustc_session::parse::ParseSess; -use rustc_span::Symbol; -use rustc_span::symbol::{self, kw}; +use rustc_span::symbol; use crate::macros::MacroArg; use crate::rewrite::RewriteContext; @@ -82,18 +81,18 @@ pub(crate) struct ParsedMacroArgs { } fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option { - for &keyword in RUST_KW.iter() { - if parser.token.is_keyword(keyword) - && parser.look_ahead(1, |t| *t == TokenKind::Eof || *t == TokenKind::Comma) - { - parser.bump(); - return Some(MacroArg::Keyword( - symbol::Ident::with_dummy_span(keyword), - parser.prev_token.span, - )); - } + if parser.token.is_any_keyword() + && parser.look_ahead(1, |t| *t == TokenKind::Eof || *t == TokenKind::Comma) + { + let keyword = parser.token.ident().unwrap().0.name; + parser.bump(); + Some(MacroArg::Keyword( + symbol::Ident::with_dummy_span(keyword), + parser.prev_token.span, + )) + } else { + None } - None } pub(crate) fn parse_macro_args( @@ -169,65 +168,3 @@ pub(crate) fn parse_expr( let mut parser = build_parser(context, tokens); parser.parse_expr().ok() } - -const RUST_KW: [Symbol; 59] = [ - kw::PathRoot, - kw::DollarCrate, - kw::Underscore, - kw::As, - kw::Box, - kw::Break, - kw::Const, - kw::Continue, - kw::Crate, - kw::Else, - kw::Enum, - kw::Extern, - kw::False, - kw::Fn, - kw::For, - kw::If, - kw::Impl, - kw::In, - kw::Let, - kw::Loop, - kw::Match, - kw::Mod, - kw::Move, - kw::Mut, - kw::Pub, - kw::Ref, - kw::Return, - kw::SelfLower, - kw::SelfUpper, - kw::Static, - kw::Struct, - kw::Super, - kw::Trait, - kw::True, - kw::Type, - kw::Unsafe, - kw::Use, - kw::Where, - kw::While, - kw::Abstract, - kw::Become, - kw::Do, - kw::Final, - kw::Macro, - kw::Override, - kw::Priv, - kw::Typeof, - kw::Unsized, - kw::Virtual, - kw::Yield, - kw::Dyn, - kw::Async, - kw::Try, - kw::UnderscoreLifetime, - kw::StaticLifetime, - kw::Auto, - kw::Catch, - kw::Default, - kw::Union, -]; diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 28b4c2b612f..f357aed66c2 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -1,11 +1,10 @@ use std::panic::{AssertUnwindSafe, catch_unwind}; use std::path::{Path, PathBuf}; -use rustc_ast::token::TokenKind; use rustc_ast::{ast, attr, ptr}; use rustc_errors::Diag; use rustc_parse::parser::Parser as RawParser; -use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; +use rustc_parse::{exp, new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal}; use rustc_span::{Span, sym}; use thin_vec::ThinVec; @@ -107,7 +106,7 @@ impl<'a> Parser<'a> { let result = catch_unwind(AssertUnwindSafe(|| { let mut parser = unwrap_or_emit_fatal(new_parser_from_file(psess.inner(), path, Some(span))); - match parser.parse_mod(&TokenKind::Eof) { + match parser.parse_mod(exp!(Eof)) { Ok((a, i, spans)) => Some((a, i, spans.inner_span)), Err(e) => { e.emit(); diff --git a/src/parse/session.rs b/src/parse/session.rs index 54ad56ed3f3..63cc8794cea 100644 --- a/src/parse/session.rs +++ b/src/parse/session.rs @@ -3,6 +3,7 @@ use std::sync::atomic::{AtomicBool, Ordering}; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter, SilentEmitter, stderr_destination}; +use rustc_errors::registry::Registry; use rustc_errors::translation::Translate; use rustc_errors::{ColorConfig, Diag, DiagCtxt, DiagInner, Level as DiagnosticLevel}; use rustc_session::parse::ParseSess as RawParseSess; @@ -38,10 +39,10 @@ struct SilentOnIgnoredFilesEmitter { } impl SilentOnIgnoredFilesEmitter { - fn handle_non_ignoreable_error(&mut self, diag: DiagInner) { + fn handle_non_ignoreable_error(&mut self, diag: DiagInner, registry: &Registry) { self.has_non_ignorable_parser_errors = true; self.can_reset.store(false, Ordering::Release); - self.emitter.emit_diagnostic(diag); + self.emitter.emit_diagnostic(diag, registry); } } @@ -60,9 +61,9 @@ impl Emitter for SilentOnIgnoredFilesEmitter { None } - fn emit_diagnostic(&mut self, diag: DiagInner) { + fn emit_diagnostic(&mut self, diag: DiagInner, registry: &Registry) { if diag.level() == DiagnosticLevel::Fatal { - return self.handle_non_ignoreable_error(diag); + return self.handle_non_ignoreable_error(diag, registry); } if let Some(primary_span) = &diag.span.primary_span() { let file_name = self.source_map.span_to_filename(*primary_span); @@ -80,7 +81,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter { } }; } - self.handle_non_ignoreable_error(diag); + self.handle_non_ignoreable_error(diag, registry); } } @@ -358,7 +359,7 @@ mod tests { None } - fn emit_diagnostic(&mut self, _diag: DiagInner) { + fn emit_diagnostic(&mut self, _diag: DiagInner, _registry: &Registry) { self.num_emitted_errors.fetch_add(1, Ordering::Release); } } @@ -412,6 +413,7 @@ mod tests { SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), source, ); + let registry = Registry::new(&[]); let mut emitter = build_emitter( Lrc::clone(&num_emitted_errors), Lrc::clone(&can_reset_errors), @@ -420,7 +422,7 @@ mod tests { ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span)); - emitter.emit_diagnostic(fatal_diagnostic); + emitter.emit_diagnostic(fatal_diagnostic, ®istry); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } @@ -437,6 +439,7 @@ mod tests { SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), source, ); + let registry = Registry::new(&[]); let mut emitter = build_emitter( Lrc::clone(&num_emitted_errors), Lrc::clone(&can_reset_errors), @@ -445,7 +448,7 @@ mod tests { ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); - emitter.emit_diagnostic(non_fatal_diagnostic); + emitter.emit_diagnostic(non_fatal_diagnostic, ®istry); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0); assert_eq!(can_reset_errors.load(Ordering::Acquire), true); } @@ -461,6 +464,7 @@ mod tests { SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("foo.rs"))), source, ); + let registry = Registry::new(&[]); let mut emitter = build_emitter( Lrc::clone(&num_emitted_errors), Lrc::clone(&can_reset_errors), @@ -469,7 +473,7 @@ mod tests { ); let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1))); let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span)); - emitter.emit_diagnostic(non_fatal_diagnostic); + emitter.emit_diagnostic(non_fatal_diagnostic, ®istry); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1); assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } @@ -497,6 +501,7 @@ mod tests { SourceMapFileName::Real(RealFileName::LocalPath(PathBuf::from("fatal.rs"))), fatal_source, ); + let registry = Registry::new(&[]); let mut emitter = build_emitter( Lrc::clone(&num_emitted_errors), Lrc::clone(&can_reset_errors), @@ -508,9 +513,9 @@ mod tests { let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span)); let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span)); let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None); - emitter.emit_diagnostic(bar_diagnostic); - emitter.emit_diagnostic(foo_diagnostic); - emitter.emit_diagnostic(fatal_diagnostic); + emitter.emit_diagnostic(bar_diagnostic, ®istry); + emitter.emit_diagnostic(foo_diagnostic, ®istry); + emitter.emit_diagnostic(fatal_diagnostic, ®istry); assert_eq!(num_emitted_errors.load(Ordering::Acquire), 2); assert_eq!(can_reset_errors.load(Ordering::Acquire), false); } diff --git a/src/patterns.rs b/src/patterns.rs index 7e7b2908c6c..875c6441190 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -48,7 +48,8 @@ fn is_short_pattern_inner(pat: &ast::Pat) -> bool { | ast::PatKind::MacCall(..) | ast::PatKind::Slice(..) | ast::PatKind::Path(..) - | ast::PatKind::Range(..) => false, + | ast::PatKind::Range(..) + | ast::PatKind::Guard(..) => false, ast::PatKind::Tuple(ref subpats) => subpats.len() <= 1, ast::PatKind::TupleStruct(_, ref path, ref subpats) => { path.segments.len() <= 1 && subpats.len() <= 1 @@ -335,8 +336,9 @@ impl Rewrite for Pat { shape.offset_left(1, self.span)?.sub_width(1, self.span)?, ) .map(|inner_pat| format!("({})", inner_pat)), - PatKind::Err(_) => Err(RewriteError::Unknown), + PatKind::Guard(..) => Ok(context.snippet(self.span).to_string()), PatKind::Deref(_) => Err(RewriteError::Unknown), + PatKind::Err(_) => Err(RewriteError::Unknown), } } } diff --git a/src/spanned.rs b/src/spanned.rs index db7c3486e71..6b3e40b9115 100644 --- a/src/spanned.rs +++ b/src/spanned.rs @@ -144,6 +144,7 @@ impl Spanned for ast::GenericParam { impl Spanned for ast::FieldDef { fn span(&self) -> Span { + // FIXME(default_field_values): This needs to be adjusted. span_with_attrs_lo_hi!(self, self.span.lo(), self.ty.span.hi()) } } diff --git a/src/types.rs b/src/types.rs index 5d52241342a..6180a4dac13 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1004,6 +1004,28 @@ impl Rewrite for ast::Ty { let pat = pat.rewrite_result(context, shape)?; Ok(format!("{ty} is {pat}")) } + ast::TyKind::UnsafeBinder(ref binder) => { + let mut result = String::new(); + if let Some(ref lifetime_str) = + rewrite_bound_params(context, shape, &binder.generic_params) + { + result.push_str("unsafe<"); + result.push_str(lifetime_str); + result.push_str("> "); + } + + let inner_ty_shape = if context.use_block_indent() { + shape.offset_left(result.len(), self.span())? + } else { + shape + .visual_indent(result.len()) + .sub_width(result.len(), self.span())? + }; + + let rewrite = binder.inner_ty.rewrite_result(context, inner_ty_shape)?; + result.push_str(&rewrite); + Ok(result) + } } } } diff --git a/src/utils.rs b/src/utils.rs index 0ca34a79491..ba4a4c045f1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -504,6 +504,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::IncludedBytes(..) | ast::ExprKind::InlineAsm(..) | ast::ExprKind::OffsetOf(..) + | ast::ExprKind::UnsafeBinderCast(..) | ast::ExprKind::Let(..) | ast::ExprKind::Path(..) | ast::ExprKind::Range(..) diff --git a/src/visitor.rs b/src/visitor.rs index 3621862a92b..59e52d687d0 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -927,7 +927,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { let ident_str = rewrite_ident(&self.get_context(), ident).to_owned(); self.push_str(&ident_str); - if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans) = mod_kind { + if let ast::ModKind::Loaded(ref items, ast::Inline::Yes, ref spans, _) = mod_kind { let ast::ModSpans { inner_span, inject_use_span: _, diff --git a/tests/source/default-field-values.rs b/tests/source/default-field-values.rs new file mode 100644 index 00000000000..622f9640d0d --- /dev/null +++ b/tests/source/default-field-values.rs @@ -0,0 +1,18 @@ +#![feature(default_struct_values)] + +// Test for now that nightly default field values are left alone for now. + +struct Foo { + default_field: Spacing = /* uwu */ 0, +} + +struct Foo2 { + #[rustfmt::skip] + default_field: Spacing = /* uwu */ 0, +} + +a_macro!( + struct Foo2 { + default_field: Spacing = /* uwu */ 0, + } +); diff --git a/tests/source/unsafe-binders.rs b/tests/source/unsafe-binders.rs new file mode 100644 index 00000000000..df23cd172bb --- /dev/null +++ b/tests/source/unsafe-binders.rs @@ -0,0 +1,13 @@ +#![feature(unsafe_binders)] + +fn foo() -> unsafe<'a> +&'a () {} + +struct Foo { + x: unsafe<'a> +&'a (), +} + +struct Bar(unsafe<'a> &'a ()); + +impl Trait for unsafe<'a> &'a () {} diff --git a/tests/target/default-field-values.rs b/tests/target/default-field-values.rs new file mode 100644 index 00000000000..622f9640d0d --- /dev/null +++ b/tests/target/default-field-values.rs @@ -0,0 +1,18 @@ +#![feature(default_struct_values)] + +// Test for now that nightly default field values are left alone for now. + +struct Foo { + default_field: Spacing = /* uwu */ 0, +} + +struct Foo2 { + #[rustfmt::skip] + default_field: Spacing = /* uwu */ 0, +} + +a_macro!( + struct Foo2 { + default_field: Spacing = /* uwu */ 0, + } +); diff --git a/tests/target/guard_patterns.rs b/tests/target/guard_patterns.rs new file mode 100644 index 00000000000..2e4667b916c --- /dev/null +++ b/tests/target/guard_patterns.rs @@ -0,0 +1,12 @@ +#![feature(guard_patterns)] + +fn main() { + match user.subscription_plan() { + (Plan::Regular if user.credit() >= 100) | (Plan::Premium if user.credit() >= 80) => { + // Complete the transaction. + } + _ => { + // The user doesn't have enough credit, return an error message. + } + } +} diff --git a/tests/target/unsafe-binders.rs b/tests/target/unsafe-binders.rs new file mode 100644 index 00000000000..a4009637d2b --- /dev/null +++ b/tests/target/unsafe-binders.rs @@ -0,0 +1,11 @@ +#![feature(unsafe_binders)] + +fn foo() -> unsafe<'a> &'a () {} + +struct Foo { + x: unsafe<'a> &'a (), +} + +struct Bar(unsafe<'a> &'a ()); + +impl Trait for unsafe<'a> &'a () {}