diff options
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/tokentrees.rs | 3 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/unescape_error_reporting.rs | 11 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/unicode_chars.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lib.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/expr.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/generics.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/path.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/stmt.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/ty.rs | 127 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/validate_attr.rs | 2 |
16 files changed, 104 insertions, 168 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index b445ccc7ad0..010a13aefa4 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2280,31 +2280,6 @@ pub(crate) struct InvalidDynKeyword { pub span: Span, } -#[derive(Diagnostic)] -#[diag(parse_negative_bounds_not_supported)] -pub(crate) struct NegativeBoundsNotSupported { - #[primary_span] - pub negative_bounds: Vec<Span>, - #[label] - pub last_span: Span, - #[subdiagnostic] - pub sub: Option<NegativeBoundsNotSupportedSugg>, -} - -#[derive(Subdiagnostic)] -#[suggestion( - parse_suggestion, - style = "tool-only", - code = "{fixed}", - applicability = "machine-applicable" -)] -pub(crate) struct NegativeBoundsNotSupportedSugg { - #[primary_span] - pub bound_list: Span, - pub num_bounds: usize, - pub fixed: String, -} - #[derive(Subdiagnostic)] pub enum HelpUseLatestEdition { #[help(parse_help_set_edition_cargo)] @@ -2412,10 +2387,12 @@ pub(crate) struct TildeConstLifetime { } #[derive(Diagnostic)] -#[diag(parse_maybe_lifetime)] -pub(crate) struct MaybeLifetime { +#[diag(parse_modifier_lifetime)] +pub(crate) struct ModifierLifetime { #[primary_span] + #[suggestion(style = "tool-only", applicability = "maybe-incorrect", code = "")] pub span: Span, + pub sigil: &'static str, } #[derive(Diagnostic)] diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index a4a75fcb969..b1c0dedd3c7 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -321,7 +321,7 @@ impl<'a> StringReader<'a> { ) -> DiagnosticBuilder<'a, !> { self.sess .span_diagnostic - .struct_span_fatal(self.mk_sp(from_pos, to_pos), &format!("{}: {}", m, escaped_char(c))) + .struct_span_fatal(self.mk_sp(from_pos, to_pos), format!("{}: {}", m, escaped_char(c))) } /// Detect usages of Unicode codepoints changing the direction of the text on screen and loudly @@ -542,7 +542,7 @@ impl<'a> StringReader<'a> { err.span_label(self.mk_sp(start, start), "unterminated raw string"); if n_hashes > 0 { - err.note(&format!( + err.note(format!( "this raw string should be terminated with `\"{}`", "#".repeat(n_hashes as usize) )); diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index 7c2c0895193..318a2998509 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -199,8 +199,7 @@ impl<'a> TokenTreesReader<'a> { // matching opening delimiter). let token_str = token_to_string(&self.token); let msg = format!("unexpected closing delimiter: `{}`", token_str); - let mut err = - self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, &msg); + let mut err = self.string_reader.sess.span_diagnostic.struct_span_err(self.token.span, msg); report_suspicious_mismatch_block( &mut err, diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 0d12ec6081d..d8bcf816fb2 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -129,7 +129,7 @@ pub(crate) fn emit_unescape_error( let label = if mode.is_byte() { "unknown byte escape" } else { "unknown character escape" }; let ec = escaped_char(c); - let mut diag = handler.struct_span_err(span, &format!("{}: `{}`", label, ec)); + let mut diag = handler.struct_span_err(span, format!("{}: `{}`", label, ec)); diag.span_label(span, label); if c == '{' || c == '}' && !mode.is_byte() { diag.help( @@ -180,13 +180,13 @@ pub(crate) fn emit_unescape_error( } else { String::new() }; - err.span_label(span, &format!("must be ASCII{}", postfix)); + err.span_label(span, format!("must be ASCII{}", postfix)); // Note: the \\xHH suggestions are not given for raw byte string // literals, because they are araw and so cannot use any escapes. if (c as u32) <= 0xFF && mode != Mode::RawByteStr { err.span_suggestion( span, - &format!( + format!( "if you meant to use the unicode code point for {:?}, use a \\xHH escape", c ), @@ -200,10 +200,7 @@ pub(crate) fn emit_unescape_error( utf8.push(c); err.span_suggestion( span, - &format!( - "if you meant to use the UTF-8 encoding of {:?}, use \\xHH escapes", - c - ), + format!("if you meant to use the UTF-8 encoding of {:?}, use \\xHH escapes", c), utf8.as_bytes() .iter() .map(|b: &u8| format!("\\x{:X}", *b)) diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs index 1f027c08fc3..829d9693e55 100644 --- a/compiler/rustc_parse/src/lexer/unicode_chars.rs +++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs @@ -350,7 +350,7 @@ pub(super) fn check_for_substitution( let Some((_, ascii_name, token)) = ASCII_ARRAY.iter().find(|&&(s, _, _)| s == ascii_str) else { let msg = format!("substitution character not found for '{}'", ch); - reader.sess.span_diagnostic.span_bug_no_panic(span, &msg); + reader.sess.span_diagnostic.span_bug_no_panic(span, msg); return (None, None); }; diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs index 61a1cdeb540..25de7808532 100644 --- a/compiler/rustc_parse/src/lib.rs +++ b/compiler/rustc_parse/src/lib.rs @@ -153,7 +153,7 @@ fn try_file_to_source_file( ) -> Result<Lrc<SourceFile>, Diagnostic> { sess.source_map().load_file(path).map_err(|e| { let msg = format!("couldn't read {}: {}", path.display(), e); - let mut diag = Diagnostic::new(Level::Fatal, &msg); + let mut diag = Diagnostic::new(Level::Fatal, msg); if let Some(sp) = spanopt { diag.set_span(sp); } @@ -190,7 +190,7 @@ pub fn maybe_file_to_stream( override_span: Option<Span>, ) -> Result<TokenStream, Vec<Diagnostic>> { let src = source_file.src.as_ref().unwrap_or_else(|| { - sess.span_diagnostic.bug(&format!( + sess.span_diagnostic.bug(format!( "cannot lex `source_file` without source: {}", sess.source_map().filename_for_diagnostics(&source_file.name) )); @@ -247,7 +247,7 @@ pub fn parse_cfg_attr( match parse_in(parse_sess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) { Ok(r) => return Some(r), Err(mut e) => { - e.help(&format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP)) + e.help(format!("the valid syntax is `{}`", CFG_ATTR_GRAMMAR_HELP)) .note(CFG_ATTR_NOTE_REF) .emit(); } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 638a432cea5..36883bd2172 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -207,11 +207,11 @@ struct MultiSugg { impl MultiSugg { fn emit(self, err: &mut Diagnostic) { - err.multipart_suggestion(&self.msg, self.patches, self.applicability); + err.multipart_suggestion(self.msg, self.patches, self.applicability); } fn emit_verbose(self, err: &mut Diagnostic) { - err.multipart_suggestion_verbose(&self.msg, self.patches, self.applicability); + err.multipart_suggestion_verbose(self.msg, self.patches, self.applicability); } } @@ -591,13 +591,13 @@ impl<'a> Parser<'a> { }; self.last_unexpected_token_span = Some(self.token.span); // FIXME: translation requires list formatting (for `expect`) - let mut err = self.struct_span_err(self.token.span, &msg_exp); + let mut err = self.struct_span_err(self.token.span, msg_exp); if let TokenKind::Ident(symbol, _) = &self.prev_token.kind { if ["def", "fun", "func", "function"].contains(&symbol.as_str()) { err.span_suggestion_short( self.prev_token.span, - &format!("write `fn` instead of `{symbol}` to declare a function"), + format!("write `fn` instead of `{symbol}` to declare a function"), "fn", Applicability::MachineApplicable, ); @@ -695,13 +695,13 @@ impl<'a> Parser<'a> { err.set_span(span); err.span_suggestion( span, - &format!("remove the extra `#`{}", pluralize!(count)), + format!("remove the extra `#`{}", pluralize!(count)), "", Applicability::MachineApplicable, ); err.span_label( str_span, - &format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)), + format!("this raw string started with {n_hashes} `#`{}", pluralize!(n_hashes)), ); true } @@ -1284,7 +1284,7 @@ impl<'a> Parser<'a> { } self.bump(); // `+` - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds()?; let sum_span = ty.span.to(self.prev_token.span); let sub = match &ty.kind { @@ -1360,12 +1360,12 @@ impl<'a> Parser<'a> { ) -> PResult<'a, P<Expr>> { let mut err = self.struct_span_err( op_span, - &format!("Rust has no {} {} operator", kind.fixity, kind.op.name()), + format!("Rust has no {} {} operator", kind.fixity, kind.op.name()), ); - err.span_label(op_span, &format!("not a valid {} operator", kind.fixity)); + err.span_label(op_span, format!("not a valid {} operator", kind.fixity)); let help_base_case = |mut err: DiagnosticBuilder<'_, _>, base| { - err.help(&format!("use `{}= 1` instead", kind.op.chr())); + err.help(format!("use `{}= 1` instead", kind.op.chr())); err.emit(); Ok(base) }; @@ -1554,7 +1554,7 @@ impl<'a> Parser<'a> { _ => this_token_str, }, ); - let mut err = self.struct_span_err(sp, &msg); + let mut err = self.struct_span_err(sp, msg); let label_exp = format!("expected `{token_str}`"); let sm = self.sess.source_map(); if !sm.is_multiline(prev_sp.until(sp)) { @@ -1705,7 +1705,7 @@ impl<'a> Parser<'a> { Applicability::MachineApplicable, ); } - err.span_suggestion(lo.shrink_to_lo(), &format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); + err.span_suggestion(lo.shrink_to_lo(), format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable); err.emit(); Ok(self.mk_expr_err(lo.to(hi))) } else { @@ -2060,7 +2060,7 @@ impl<'a> Parser<'a> { format!("expected expression, found {}", super::token_descr(&self.token),), ), }; - let mut err = self.struct_span_err(span, &msg); + let mut err = self.struct_span_err(span, msg); let sp = self.sess.source_map().start_point(self.token.span); if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&sp) { err.subdiagnostic(ExprParenthesesNeeded::surrounding(*sp)); @@ -2131,7 +2131,7 @@ impl<'a> Parser<'a> { // arguments after a comma. let mut err = self.struct_span_err( self.token.span, - &format!("expected one of `,` or `>`, found {}", super::token_descr(&self.token)), + format!("expected one of `,` or `>`, found {}", super::token_descr(&self.token)), ); err.span_label(self.token.span, "expected one of `,` or `>`"); match self.recover_const_arg(arg.span(), err) { @@ -2558,7 +2558,7 @@ impl<'a> Parser<'a> { let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern"); if let Ok(seq_snippet) = self.span_to_snippet(seq_span) { err.multipart_suggestion( - &format!( + format!( "try adding parentheses to match on a tuple{}", if let CommaRecoveryMode::LikelyTuple = rt { "" } else { "..." }, ), diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 02db4b095dc..f58f8919e5c 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -855,7 +855,7 @@ impl<'a> Parser<'a> { _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"), } ); - let mut err = self.struct_span_err(span, &msg); + let mut err = self.struct_span_err(span, msg); let suggest_parens = |err: &mut Diagnostic| { let suggestions = vec![ @@ -1803,7 +1803,7 @@ impl<'a> Parser<'a> { let token = self.token.clone(); let err = |self_: &Self| { let msg = format!("unexpected token: {}", super::token_descr(&token)); - self_.struct_span_err(token.span, &msg) + self_.struct_span_err(token.span, msg) }; // On an error path, eagerly consider a lifetime to be an unclosed character lit if self.token.is_lifetime() { diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs index 61a7ae93bfa..e6d0f9fbc76 100644 --- a/compiler/rustc_parse/src/parser/generics.rs +++ b/compiler/rustc_parse/src/parser/generics.rs @@ -78,7 +78,7 @@ impl<'a> Parser<'a> { } self.restore_snapshot(snapshot); } - self.parse_generic_bounds(colon_span)? + self.parse_generic_bounds()? } else { Vec::new() }; @@ -419,7 +419,7 @@ impl<'a> Parser<'a> { // or with mandatory equality sign and the second type. let ty = self.parse_ty_for_where_clause()?; if self.eat(&token::Colon) { - let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?; + let bounds = self.parse_generic_bounds()?; Ok(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { span: lo.to(self.prev_token.span), bound_generic_params: lifetime_defs, diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 64ff7f1fb2c..6ca88200dc5 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -71,7 +71,7 @@ impl<'a> Parser<'a> { if !self.eat(term) { let token_str = super::token_descr(&self.token); if !self.maybe_consume_incorrect_semicolon(&items) { - let msg = &format!("expected item, found {token_str}"); + let msg = format!("expected item, found {token_str}"); let mut err = self.struct_span_err(self.token.span, msg); let label = if self.is_kw_followed_by_ident(kw::Let) { "consider using `const` or `static` instead of `let` for global variables" @@ -788,11 +788,7 @@ impl<'a> Parser<'a> { // Parse optional colon and supertrait bounds. let had_colon = self.eat(&token::Colon); let span_at_colon = self.prev_token.span; - let bounds = if had_colon { - self.parse_generic_bounds(Some(self.prev_token.span))? - } else { - Vec::new() - }; + let bounds = if had_colon { self.parse_generic_bounds()? } else { Vec::new() }; let span_before_eq = self.prev_token.span; if self.eat(&token::Eq) { @@ -802,7 +798,7 @@ impl<'a> Parser<'a> { self.sess.emit_err(errors::BoundsNotAllowedOnTraitAliases { span }); } - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds()?; generics.where_clause = self.parse_where_clause()?; self.expect_semi()?; @@ -883,7 +879,7 @@ impl<'a> Parser<'a> { // Parse optional colon and param bounds. let bounds = - if self.eat(&token::Colon) { self.parse_generic_bounds(None)? } else { Vec::new() }; + if self.eat(&token::Colon) { self.parse_generic_bounds()? } else { Vec::new() }; let before_where_clause = self.parse_where_clause()?; let ty = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None }; @@ -1429,7 +1425,7 @@ impl<'a> Parser<'a> { VariantData::Struct(fields, recovered) } else { let token_str = super::token_descr(&self.token); - let msg = &format!("expected `where` or `{{` after union name, found {token_str}"); + let msg = format!("expected `where` or `{{` after union name, found {token_str}"); let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `where` or `{` after union name"); return Err(err); @@ -1465,7 +1461,7 @@ impl<'a> Parser<'a> { self.eat(&token::CloseDelim(Delimiter::Brace)); } else { let token_str = super::token_descr(&self.token); - let msg = &format!( + let msg = format!( "expected {}`{{` after struct name, found {}", if parsed_where { "" } else { "`where`, or " }, token_str @@ -1602,7 +1598,7 @@ impl<'a> Parser<'a> { let sp = self.prev_token.span.shrink_to_hi(); let mut err = self.struct_span_err( sp, - &format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)), + format!("expected `,`, or `}}`, found {}", super::token_descr(&self.token)), ); // Try to recover extra trailing angle brackets @@ -1740,7 +1736,7 @@ impl<'a> Parser<'a> { Ok(_) => { let mut err = self.struct_span_err( lo.to(self.prev_token.span), - &format!("functions are not allowed in {adt_ty} definitions"), + format!("functions are not allowed in {adt_ty} definitions"), ); err.help( "unlike in C++, Java, and C#, functions are declared in `impl` blocks", @@ -1759,7 +1755,7 @@ impl<'a> Parser<'a> { Ok((ident, _)) => { let mut err = self.struct_span_err( lo.with_hi(ident.span.hi()), - &format!("structs are not allowed in {adt_ty} definitions"), + format!("structs are not allowed in {adt_ty} definitions"), ); err.help("consider creating a new `struct` definition instead of nesting"); err @@ -2228,11 +2224,11 @@ impl<'a> Parser<'a> { err.span_suggestion( self.token.uninterpolated_span(), - &format!("`{original_kw}` already used earlier, remove this one"), + format!("`{original_kw}` already used earlier, remove this one"), "", Applicability::MachineApplicable, ) - .span_note(original_sp, &format!("`{original_kw}` first seen here")); + .span_note(original_sp, format!("`{original_kw}` first seen here")); } // The keyword has not been seen yet, suggest correct placement in the function front matter else if let Some(WrongKw::Misplaced(correct_pos_sp)) = wrong_kw { @@ -2243,7 +2239,7 @@ impl<'a> Parser<'a> { err.span_suggestion( correct_pos_sp.to(misplaced_qual_sp), - &format!("`{misplaced_qual}` must come before `{current_qual}`"), + format!("`{misplaced_qual}` must come before `{current_qual}`"), format!("{misplaced_qual} {current_qual}"), Applicability::MachineApplicable, ).note("keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`"); @@ -2267,7 +2263,7 @@ impl<'a> Parser<'a> { if matches!(orig_vis.kind, VisibilityKind::Inherited) { err.span_suggestion( sp_start.to(self.prev_token.span), - &format!("visibility `{vs}` must come before `{snippet}`"), + format!("visibility `{vs}` must come before `{snippet}`"), format!("{vs} {snippet}"), Applicability::MachineApplicable, ); diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index b294e13402a..0c265d7af0e 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -905,7 +905,7 @@ impl<'a> Parser<'a> { expect_err .span_suggestion_verbose( self.prev_token.span.shrink_to_hi().until(self.token.span), - &msg, + msg, " @ ", Applicability::MaybeIncorrect, ) @@ -921,7 +921,7 @@ impl<'a> Parser<'a> { expect_err .span_suggestion_short( sp, - &format!("missing `{}`", token_str), + format!("missing `{}`", token_str), token_str, Applicability::MaybeIncorrect, ) diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 3c4b2977af9..c317d96368e 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -444,7 +444,7 @@ impl<'a> Parser<'a> { super::token_descr(&self_.token) ); - let mut err = self_.struct_span_err(self_.token.span, &msg); + let mut err = self_.struct_span_err(self_.token.span, msg); err.span_label(self_.token.span, format!("expected {}", expected)); err }); @@ -680,7 +680,7 @@ impl<'a> Parser<'a> { let expected = Expected::to_string_or_fallback(expected); let msg = format!("expected {}, found {}", expected, super::token_descr(&self.token)); - let mut err = self.struct_span_err(self.token.span, &msg); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, format!("expected {}", expected)); let sp = self.sess.source_map().start_point(self.token.span); @@ -978,7 +978,7 @@ impl<'a> Parser<'a> { break; } let token_str = super::token_descr(&self.token); - let msg = &format!("expected `}}`, found {}", token_str); + let msg = format!("expected `}}`, found {}", token_str); let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected `}`"); diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index b9a2b141bce..feb7e829caf 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -606,7 +606,7 @@ impl<'a> Parser<'a> { let kind = if self.eat(&token::Colon) { // Parse associated type constraint bound. - let bounds = self.parse_generic_bounds(Some(self.prev_token.span))?; + let bounds = self.parse_generic_bounds()?; AssocConstraintKind::Bound { bounds } } else if self.eat(&token::Eq) { self.parse_assoc_equality_term(ident, self.prev_token.span)? @@ -679,14 +679,14 @@ impl<'a> Parser<'a> { ); err.span_suggestion( eq.to(before_next), - &format!("remove the `=` if `{}` is a type", ident), + format!("remove the `=` if `{}` is a type", ident), "", Applicability::MaybeIncorrect, ) } else { err.span_label( self.token.span, - &format!("expected type, found {}", super::token_descr(&self.token)), + format!("expected type, found {}", super::token_descr(&self.token)), ) }; return Err(err); diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 0a571013d44..1c17de337e8 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -634,7 +634,7 @@ impl<'a> Parser<'a> { e.span_suggestion( sp.with_hi(sp.lo() + BytePos(marker.len() as u32)), - &format!( + format!( "add a space before `{}` to use a regular comment", doc_comment_marker, ), diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 37c441fbecb..a29b696aea8 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -3,8 +3,7 @@ use super::{Parser, PathStyle, TokenType}; use crate::errors::{ self, DynAfterMut, ExpectedFnPathFoundFnKeyword, ExpectedMutOrConstInRawPointerType, FnPointerCannotBeAsync, FnPointerCannotBeConst, FnPtrWithGenerics, FnPtrWithGenericsSugg, - InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, - NegativeBoundsNotSupported, NegativeBoundsNotSupportedSugg, NestedCVariadicType, + InvalidDynKeyword, LifetimeAfterMut, NeedPlusAfterTraitObjectLifetime, NestedCVariadicType, ReturnTypesUseThinArrow, }; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; @@ -14,8 +13,9 @@ use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::util::case::Case; use rustc_ast::{ - self as ast, BareFnTy, FnRetTy, GenericBound, GenericBounds, GenericParam, Generics, Lifetime, - MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, Ty, TyKind, + self as ast, BareFnTy, BoundPolarity, FnRetTy, GenericBound, GenericBounds, GenericParam, + Generics, Lifetime, MacCall, MutTy, Mutability, PolyTraitRef, TraitBoundModifier, + TraitObjectSyntax, Ty, TyKind, }; use rustc_errors::{Applicability, PResult}; use rustc_span::source_map::Span; @@ -23,10 +23,10 @@ use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Symbol; use thin_vec::{thin_vec, ThinVec}; -/// Any `?` or `~const` modifiers that appear at the start of a bound. +/// Any `?`, `!`, or `~const` modifiers that appear at the start of a bound. struct BoundModifiers { /// `?Trait`. - maybe: Option<Span>, + bound_polarity: BoundPolarity, /// `~const Trait`. maybe_const: Option<Span>, @@ -34,11 +34,13 @@ struct BoundModifiers { impl BoundModifiers { fn to_trait_bound_modifier(&self) -> TraitBoundModifier { - match (self.maybe, self.maybe_const) { - (None, None) => TraitBoundModifier::None, - (Some(_), None) => TraitBoundModifier::Maybe, - (None, Some(_)) => TraitBoundModifier::MaybeConst, - (Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe, + match (self.bound_polarity, self.maybe_const) { + (BoundPolarity::Positive, None) => TraitBoundModifier::None, + (BoundPolarity::Negative(_), None) => TraitBoundModifier::Negative, + (BoundPolarity::Maybe(_), None) => TraitBoundModifier::Maybe, + (BoundPolarity::Positive, Some(_)) => TraitBoundModifier::MaybeConst, + (BoundPolarity::Negative(_), Some(_)) => TraitBoundModifier::MaybeConstNegative, + (BoundPolarity::Maybe(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe, } } } @@ -315,7 +317,7 @@ impl<'a> Parser<'a> { } } else { let msg = format!("expected type, found {}", super::token_descr(&self.token)); - let mut err = self.struct_span_err(self.token.span, &msg); + let mut err = self.struct_span_err(self.token.span, msg); err.span_label(self.token.span, "expected type"); return Err(err); }; @@ -368,7 +370,7 @@ impl<'a> Parser<'a> { fn parse_bare_trait_object(&mut self, lo: Span, allow_plus: AllowPlus) -> PResult<'a, TyKind> { let lt_no_plus = self.check_lifetime() && !self.look_ahead(1, |t| t.is_like_plus()); - let bounds = self.parse_generic_bounds_common(allow_plus, None)?; + let bounds = self.parse_generic_bounds_common(allow_plus)?; if lt_no_plus { self.sess.emit_err(NeedPlusAfterTraitObjectLifetime { span: lo }); } @@ -395,7 +397,7 @@ impl<'a> Parser<'a> { ) -> PResult<'a, TyKind> { if plus { self.eat_plus(); // `+`, or `+=` gets split and `+` is discarded - bounds.append(&mut self.parse_generic_bounds(Some(self.prev_token.span))?); + bounds.append(&mut self.parse_generic_bounds()?); } Ok(TyKind::TraitObject(bounds, TraitObjectSyntax::None)) } @@ -598,7 +600,7 @@ impl<'a> Parser<'a> { } }) } - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds()?; *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus); Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds)) } @@ -629,7 +631,7 @@ impl<'a> Parser<'a> { }; // Always parse bounds greedily for better error recovery. - let bounds = self.parse_generic_bounds(None)?; + let bounds = self.parse_generic_bounds()?; *impl_dyn_multi = bounds.len() > 1 || self.prev_token.kind == TokenKind::BinOp(token::Plus); Ok(TyKind::TraitObject(bounds, syntax)) } @@ -660,23 +662,15 @@ impl<'a> Parser<'a> { } } - pub(super) fn parse_generic_bounds( - &mut self, - colon_span: Option<Span>, - ) -> PResult<'a, GenericBounds> { - self.parse_generic_bounds_common(AllowPlus::Yes, colon_span) + pub(super) fn parse_generic_bounds(&mut self) -> PResult<'a, GenericBounds> { + self.parse_generic_bounds_common(AllowPlus::Yes) } /// Parses bounds of a type parameter `BOUND + BOUND + ...`, possibly with trailing `+`. /// /// See `parse_generic_bound` for the `BOUND` grammar. - fn parse_generic_bounds_common( - &mut self, - allow_plus: AllowPlus, - colon_span: Option<Span>, - ) -> PResult<'a, GenericBounds> { + fn parse_generic_bounds_common(&mut self, allow_plus: AllowPlus) -> PResult<'a, GenericBounds> { let mut bounds = Vec::new(); - let mut negative_bounds = Vec::new(); // In addition to looping while we find generic bounds: // We continue even if we find a keyword. This is necessary for error recovery on, @@ -693,19 +687,12 @@ impl<'a> Parser<'a> { self.sess.emit_err(InvalidDynKeyword { span: self.token.span }); self.bump(); } - match self.parse_generic_bound()? { - Ok(bound) => bounds.push(bound), - Err(neg_sp) => negative_bounds.push(neg_sp), - } + bounds.push(self.parse_generic_bound()?); if allow_plus == AllowPlus::No || !self.eat_plus() { break; } } - if !negative_bounds.is_empty() { - self.error_negative_bounds(colon_span, &bounds, negative_bounds); - } - Ok(bounds) } @@ -713,55 +700,22 @@ impl<'a> Parser<'a> { fn can_begin_bound(&mut self) -> bool { // This needs to be synchronized with `TokenKind::can_begin_bound`. self.check_path() - || self.check_lifetime() - || self.check(&token::Not) // Used for error reporting only. - || self.check(&token::Question) - || self.check(&token::Tilde) - || self.check_keyword(kw::For) - || self.check(&token::OpenDelim(Delimiter::Parenthesis)) - } - - fn error_negative_bounds( - &self, - colon_span: Option<Span>, - bounds: &[GenericBound], - negative_bounds: Vec<Span>, - ) { - let sub = if let Some(bound_list) = colon_span { - let bound_list = bound_list.to(self.prev_token.span); - let mut new_bound_list = String::new(); - if !bounds.is_empty() { - let mut snippets = bounds.iter().map(|bound| self.span_to_snippet(bound.span())); - while let Some(Ok(snippet)) = snippets.next() { - new_bound_list.push_str(" + "); - new_bound_list.push_str(&snippet); - } - new_bound_list = new_bound_list.replacen(" +", ":", 1); - } - - Some(NegativeBoundsNotSupportedSugg { - bound_list, - num_bounds: negative_bounds.len(), - fixed: new_bound_list, - }) - } else { - None - }; - - let last_span = *negative_bounds.last().expect("no negative bounds, but still error?"); - self.sess.emit_err(NegativeBoundsNotSupported { negative_bounds, last_span, sub }); + || self.check_lifetime() + || self.check(&token::Not) + || self.check(&token::Question) + || self.check(&token::Tilde) + || self.check_keyword(kw::For) + || self.check(&token::OpenDelim(Delimiter::Parenthesis)) } /// Parses a bound according to the grammar: /// ```ebnf /// BOUND = TY_BOUND | LT_BOUND /// ``` - fn parse_generic_bound(&mut self) -> PResult<'a, Result<GenericBound, Span>> { - let anchor_lo = self.prev_token.span; + fn parse_generic_bound(&mut self) -> PResult<'a, GenericBound> { let lo = self.token.span; let has_parens = self.eat(&token::OpenDelim(Delimiter::Parenthesis)); let inner_lo = self.token.span; - let is_negative = self.eat(&token::Not); let modifiers = self.parse_ty_bound_modifiers()?; let bound = if self.token.is_lifetime() { @@ -771,7 +725,7 @@ impl<'a> Parser<'a> { self.parse_generic_ty_bound(lo, has_parens, modifiers)? }; - Ok(if is_negative { Err(anchor_lo.to(self.prev_token.span)) } else { Ok(bound) }) + Ok(bound) } /// Parses a lifetime ("outlives") bound, e.g. `'a`, according to: @@ -799,8 +753,14 @@ impl<'a> Parser<'a> { self.sess.emit_err(errors::TildeConstLifetime { span }); } - if let Some(span) = modifiers.maybe { - self.sess.emit_err(errors::MaybeLifetime { span }); + match modifiers.bound_polarity { + BoundPolarity::Positive => {} + BoundPolarity::Negative(span) => { + self.sess.emit_err(errors::ModifierLifetime { span, sigil: "!" }); + } + BoundPolarity::Maybe(span) => { + self.sess.emit_err(errors::ModifierLifetime { span, sigil: "?" }); + } } } @@ -843,9 +803,16 @@ impl<'a> Parser<'a> { None }; - let maybe = self.eat(&token::Question).then_some(self.prev_token.span); + let bound_polarity = if self.eat(&token::Question) { + BoundPolarity::Maybe(self.prev_token.span) + } else if self.eat(&token::Not) { + self.sess.gated_spans.gate(sym::negative_bounds, self.prev_token.span); + BoundPolarity::Negative(self.prev_token.span) + } else { + BoundPolarity::Positive + }; - Ok(BoundModifiers { maybe, maybe_const }) + Ok(BoundModifiers { bound_polarity, maybe_const }) } /// Parses a type bound according to: diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index 815b7c85679..982c4615aff 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -189,7 +189,7 @@ fn emit_malformed_attribute( sess.buffer_lint(&ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, &msg); } else { sess.span_diagnostic - .struct_span_err(span, &error_msg) + .struct_span_err(span, error_msg) .span_suggestions( span, if suggestions.len() == 1 { |
