From 55806e565503f8d9e519f3c958f3c51836304cd2 Mon Sep 17 00:00:00 2001 From: Orion Gonzalez Date: Tue, 10 Dec 2024 23:19:45 +0100 Subject: document check_expr_field --- compiler/rustc_errors/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'compiler/rustc_errors/src/lib.rs') diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6232c875ee8..fc44340851c 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1291,7 +1291,7 @@ impl<'a> DiagCtxtHandle<'a> { Diag::::new(self, DelayedBug, msg.into()).emit() } - /// Ensures that an error is printed. See `Level::DelayedBug`. + /// Ensures that an error is printed. See [`Level::DelayedBug`]. /// /// Note: this function used to be called `delay_span_bug`. It was renamed /// to match similar functions like `span_err`, `span_warn`, etc. -- cgit 1.4.1-3-g733a5 From 014363e89e4347332c50daede2efa66af3c2c243 Mon Sep 17 00:00:00 2001 From: Orion Gonzalez Date: Wed, 11 Dec 2024 00:53:07 +0100 Subject: Don't emit "field expressions may not have generic arguments" if it's a method call without () --- compiler/rustc_errors/src/lib.rs | 4 ++++ compiler/rustc_hir_typeck/src/expr.rs | 3 ++- compiler/rustc_parse/src/parser/expr.rs | 7 +++++-- tests/ui/parser/bad-name.stderr | 12 ++++++------ tests/ui/suggestions/method-missing-parentheses.rs | 1 - tests/ui/suggestions/method-missing-parentheses.stderr | 8 +------- 6 files changed, 18 insertions(+), 17 deletions(-) (limited to 'compiler/rustc_errors/src/lib.rs') diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6232c875ee8..95b40b6a906 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -576,6 +576,10 @@ pub enum StashKey { UndeterminedMacroResolution, /// Used by `Parser::maybe_recover_trailing_expr` ExprInPat, + /// If in the parser we detect a field expr with turbofish generic params it's possible that + /// it's a method call without parens. If later on in `hir_typeck` we find out that this is + /// the case we suppress this message and we give a better suggestion. + GenericInFieldExpr, } fn default_track_diagnostic(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R { diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 0e079b03769..12257c449e7 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -3055,7 +3055,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.help("methods are immutable and cannot be assigned to"); } - err.emit() + // See `StashKey::GenericInFieldExpr` for more info + self.dcx().try_steal_replace_and_emit_err(field.span, StashKey::GenericInFieldExpr, err) } fn point_at_param_definition(&self, err: &mut Diag<'_>, param: ty::ParamTy) { diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index eeb83a85e59..0904a42d8a4 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1369,11 +1369,14 @@ impl<'a> Parser<'a> { )) } else { // Field access `expr.f` + let span = lo.to(self.prev_token.span); if let Some(args) = seg.args { - self.dcx().emit_err(errors::FieldExpressionWithGeneric(args.span())); + // See `StashKey::GenericInFieldExpr` for more info on why we stash this. + self.dcx() + .create_err(errors::FieldExpressionWithGeneric(args.span())) + .stash(seg.ident.span, StashKey::GenericInFieldExpr); } - let span = lo.to(self.prev_token.span); Ok(self.mk_expr(span, ExprKind::Field(self_arg, seg.ident))) } } diff --git a/tests/ui/parser/bad-name.stderr b/tests/ui/parser/bad-name.stderr index a336923f4fd..112fdcad336 100644 --- a/tests/ui/parser/bad-name.stderr +++ b/tests/ui/parser/bad-name.stderr @@ -1,9 +1,3 @@ -error: field expressions cannot have generic arguments - --> $DIR/bad-name.rs:2:12 - | -LL | let x.y::.z foo; - | ^^^^^^^ - error: expected a pattern, found an expression --> $DIR/bad-name.rs:2:7 | @@ -18,5 +12,11 @@ error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, LL | let x.y::.z foo; | ^^^ expected one of 9 possible tokens +error: field expressions cannot have generic arguments + --> $DIR/bad-name.rs:2:12 + | +LL | let x.y::.z foo; + | ^^^^^^^ + error: aborting due to 3 previous errors diff --git a/tests/ui/suggestions/method-missing-parentheses.rs b/tests/ui/suggestions/method-missing-parentheses.rs index f10bfb56d2e..bc576b71f0d 100644 --- a/tests/ui/suggestions/method-missing-parentheses.rs +++ b/tests/ui/suggestions/method-missing-parentheses.rs @@ -1,5 +1,4 @@ fn main() { let _ = vec![].into_iter().collect::; //~^ ERROR attempted to take value of method `collect` on type `std::vec::IntoIter<_>` - //~| ERROR field expressions cannot have generic arguments } diff --git a/tests/ui/suggestions/method-missing-parentheses.stderr b/tests/ui/suggestions/method-missing-parentheses.stderr index 1bfff56a6a9..f0ff1f0334a 100644 --- a/tests/ui/suggestions/method-missing-parentheses.stderr +++ b/tests/ui/suggestions/method-missing-parentheses.stderr @@ -1,9 +1,3 @@ -error: field expressions cannot have generic arguments - --> $DIR/method-missing-parentheses.rs:2:41 - | -LL | let _ = vec![].into_iter().collect::; - | ^^^^^^^ - error[E0615]: attempted to take value of method `collect` on type `std::vec::IntoIter<_>` --> $DIR/method-missing-parentheses.rs:2:32 | @@ -15,6 +9,6 @@ help: use parentheses to call the method LL | let _ = vec![].into_iter().collect::(); | ++ -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0615`. -- cgit 1.4.1-3-g733a5 From 40c964510c3d6f6c05ceee305e128bd924baf1d6 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 12 Dec 2024 11:31:10 +1100 Subject: Remove `PErr`. It's just a synonym for `Diag` that adds no value and is only used in a few places. --- compiler/rustc_errors/src/lib.rs | 3 +-- compiler/rustc_parse/src/lexer/tokentrees.rs | 14 +++++++------- compiler/rustc_parse/src/parser/diagnostics.rs | 6 +++--- 3 files changed, 11 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_errors/src/lib.rs') diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 6232c875ee8..f77f53a1310 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -94,8 +94,7 @@ mod styled_buffer; mod tests; pub mod translation; -pub type PErr<'a> = Diag<'a>; -pub type PResult<'a, T> = Result>; +pub type PResult<'a, T> = Result>; rustc_fluent_macro::fluent_messages! { "../messages.ftl" } diff --git a/compiler/rustc_parse/src/lexer/tokentrees.rs b/compiler/rustc_parse/src/lexer/tokentrees.rs index c6c9eb3b0b2..ee38f16d4ec 100644 --- a/compiler/rustc_parse/src/lexer/tokentrees.rs +++ b/compiler/rustc_parse/src/lexer/tokentrees.rs @@ -1,7 +1,7 @@ use rustc_ast::token::{self, Delimiter, Token}; use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree}; use rustc_ast_pretty::pprust::token_to_string; -use rustc_errors::{Applicability, PErr}; +use rustc_errors::{Applicability, Diag}; use rustc_span::symbol::kw; use super::diagnostics::{report_suspicious_mismatch_block, same_indentation_level}; @@ -14,7 +14,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { pub(super) fn lex_token_trees( &mut self, is_delimited: bool, - ) -> (Spacing, TokenStream, Result<(), Vec>>) { + ) -> (Spacing, TokenStream, Result<(), Vec>>) { // Move past the opening delimiter. let open_spacing = self.bump_minimal(); @@ -56,7 +56,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { } } - fn eof_err(&mut self) -> PErr<'psess> { + fn eof_err(&mut self) -> Diag<'psess> { let msg = "this file contains an unclosed delimiter"; let mut err = self.dcx().struct_span_err(self.token.span, msg); @@ -98,7 +98,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { fn lex_token_tree_open_delim( &mut self, open_delim: Delimiter, - ) -> Result>> { + ) -> Result>> { // The span for beginning of the delimited section. let pre_span = self.token.span; @@ -250,8 +250,8 @@ impl<'psess, 'src> Lexer<'psess, 'src> { fn unclosed_delim_err( &mut self, tts: TokenStream, - mut errs: Vec>, - ) -> Vec> { + mut errs: Vec>, + ) -> Vec> { // If there are unclosed delims, see if there are diff markers and if so, point them // out instead of complaining about the unclosed delims. let mut parser = Parser::new(self.psess, tts, None); @@ -308,7 +308,7 @@ impl<'psess, 'src> Lexer<'psess, 'src> { errs } - fn close_delim_err(&mut self, delim: Delimiter) -> PErr<'psess> { + fn close_delim_err(&mut self, delim: Delimiter) -> Diag<'psess> { // An unexpected closing delimiter (i.e., there is no matching opening delimiter). let token_str = token_to_string(&self.token); let msg = format!("unexpected closing delimiter: `{token_str}`"); diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 34131e3af6e..e5edf605d82 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -16,7 +16,7 @@ use rustc_ast_pretty::pprust; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::Lrc; use rustc_errors::{ - Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PErr, PResult, Subdiagnostic, + Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PResult, Subdiagnostic, Suggestions, pluralize, }; use rustc_session::errors::ExprParenthesesNeeded; @@ -2132,7 +2132,7 @@ impl<'a> Parser<'a> { &mut self, delim: Delimiter, lo: Span, - err: PErr<'a>, + err: Diag<'a>, ) -> P { let guar = err.emit(); // Recover from parse error, callers expect the closing delim to be consumed. @@ -3014,7 +3014,7 @@ impl<'a> Parser<'a> { } /// Check for exclusive ranges written as `..<` - pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: PErr<'a>) -> PErr<'a> { + pub(crate) fn maybe_err_dotdotlt_syntax(&self, maybe_lt: Token, mut err: Diag<'a>) -> Diag<'a> { if maybe_lt == token::Lt && (self.expected_tokens.contains(&TokenType::Token(token::Gt)) || matches!(self.token.kind, token::Literal(..))) -- cgit 1.4.1-3-g733a5 From fe521506a61c9ec437213882dc7b80203b81c341 Mon Sep 17 00:00:00 2001 From: The 8472 Date: Wed, 20 Nov 2024 23:45:53 +0100 Subject: update uses of extract_if in the compiler --- compiler/rustc_errors/src/lib.rs | 8 ++++---- compiler/rustc_lint/src/non_ascii_idents.rs | 4 ++-- compiler/rustc_metadata/src/native_libs.rs | 2 +- compiler/rustc_middle/src/ty/diagnostics.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 6 +++--- compiler/rustc_resolve/src/late/diagnostics.rs | 2 +- compiler/rustc_trait_selection/src/traits/mod.rs | 2 +- 7 files changed, 13 insertions(+), 13 deletions(-) (limited to 'compiler/rustc_errors/src/lib.rs') diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 25d41462556..58fe3ec4b85 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -1569,18 +1569,18 @@ impl DiagCtxtInner { debug!(?diagnostic); debug!(?self.emitted_diagnostics); - let already_emitted_sub = |sub: &mut Subdiag| { + let not_yet_emitted = |sub: &mut Subdiag| { debug!(?sub); if sub.level != OnceNote && sub.level != OnceHelp { - return false; + return true; } let mut hasher = StableHasher::new(); sub.hash(&mut hasher); let diagnostic_hash = hasher.finish(); debug!(?diagnostic_hash); - !self.emitted_diagnostics.insert(diagnostic_hash) + self.emitted_diagnostics.insert(diagnostic_hash) }; - diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {}); + diagnostic.children.retain_mut(not_yet_emitted); if already_emitted { let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`"; diagnostic.sub(Note, msg, MultiSpan::new()); diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs index 9b495c19990..50c64a9c947 100644 --- a/compiler/rustc_lint/src/non_ascii_idents.rs +++ b/compiler/rustc_lint/src/non_ascii_idents.rs @@ -205,7 +205,7 @@ impl EarlyLintPass for NonAsciiIdents { (IdentifierType::Not_NFKC, "Not_NFKC"), ] { let codepoints: Vec<_> = - chars.extract_if(|(_, ty)| *ty == Some(id_ty)).collect(); + chars.extract_if(.., |(_, ty)| *ty == Some(id_ty)).collect(); if codepoints.is_empty() { continue; } @@ -217,7 +217,7 @@ impl EarlyLintPass for NonAsciiIdents { } let remaining = chars - .extract_if(|(c, _)| !GeneralSecurityProfile::identifier_allowed(*c)) + .extract_if(.., |(c, _)| !GeneralSecurityProfile::identifier_allowed(*c)) .collect::>(); if !remaining.is_empty() { cx.emit_span_lint(UNCOMMON_CODEPOINTS, sp, IdentifierUncommonCodepoints { diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 8bd2281981b..4829befda61 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -544,7 +544,7 @@ impl<'tcx> Collector<'tcx> { // can move them to the end of the list below. let mut existing = self .libs - .extract_if(|lib| { + .extract_if(.., |lib| { if lib.name.as_str() == passed_lib.name { // FIXME: This whole logic is questionable, whether modifiers are // involved or not, library reordering and kind overriding without diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 604f1da26c6..406e732744b 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -309,7 +309,7 @@ pub fn suggest_constraining_type_params<'a>( let Some(param) = param else { return false }; { - let mut sized_constraints = constraints.extract_if(|(_, def_id, _)| { + let mut sized_constraints = constraints.extract_if(.., |(_, def_id, _)| { def_id.is_some_and(|def_id| tcx.is_lang_item(def_id, LangItem::Sized)) }); if let Some((_, def_id, _)) = sized_constraints.next() { diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 368eb3c26c7..7cd56a8fb95 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2817,11 +2817,11 @@ fn show_candidates( path_strings.sort_by(|a, b| a.0.cmp(&b.0)); path_strings.dedup_by(|a, b| a.0 == b.0); let core_path_strings = - path_strings.extract_if(|p| p.0.starts_with("core::")).collect::>(); + path_strings.extract_if(.., |p| p.0.starts_with("core::")).collect::>(); let std_path_strings = - path_strings.extract_if(|p| p.0.starts_with("std::")).collect::>(); + path_strings.extract_if(.., |p| p.0.starts_with("std::")).collect::>(); let foreign_crate_path_strings = - path_strings.extract_if(|p| !p.0.starts_with("crate::")).collect::>(); + path_strings.extract_if(.., |p| !p.0.starts_with("crate::")).collect::>(); // We list the `crate` local paths first. // Then we list the `std`/`core` paths. diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 09f3e848766..b5eb3a022d8 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -628,7 +628,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { // Try to filter out intrinsics candidates, as long as we have // some other candidates to suggest. let intrinsic_candidates: Vec<_> = candidates - .extract_if(|sugg| { + .extract_if(.., |sugg| { let path = path_names_to_string(&sugg.path); path.starts_with("core::intrinsics::") || path.starts_with("std::intrinsics::") }) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 069fab6a6e6..069d42d4018 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -447,7 +447,7 @@ pub fn normalize_param_env_or_error<'tcx>( // This works fairly well because trait matching does not actually care about param-env // TypeOutlives predicates - these are normally used by regionck. let outlives_predicates: Vec<_> = predicates - .extract_if(|predicate| { + .extract_if(.., |predicate| { matches!(predicate.kind().skip_binder(), ty::ClauseKind::TypeOutlives(..)) }) .collect(); -- cgit 1.4.1-3-g733a5