From 6e2adbf6a30334dabf20403bd0810f69972e5cf4 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 15 Sep 2023 01:05:01 +0000 Subject: [PATCH 1/5] Migrate 'explicit destructor call' diagnostic --- compiler/rustc_hir_typeck/messages.ftl | 4 +++ compiler/rustc_hir_typeck/src/callee.rs | 29 +++++++------------ compiler/rustc_hir_typeck/src/errors.rs | 23 +++++++++++++++ tests/ui/error-codes/E0040.stderr | 10 ++++--- .../ui/explicit/explicit-call-to-dtor.stderr | 10 ++++--- .../explicit-call-to-supertrait-dtor.stderr | 10 ++++--- 6 files changed, 56 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 2281343e250..d12a6a09079 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -33,6 +33,10 @@ hir_typeck_expected_default_return_type = expected `()` because of default retur hir_typeck_expected_return_type = expected `{$expected}` because of return type +hir_typeck_explicit_destructor = explicit use of destructor method + .label = explicit destructor calls not allowed + .suggestion = consider using `drop` function + hir_typeck_field_multiply_specified_in_initializer = field `{$ident}` specified more than once .label = used more than once diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 02371f85ac3..c5b2aaf2361 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -2,9 +2,10 @@ use super::method::probe::ProbeScope; use super::method::MethodCallee; use super::{Expectation, FnCtxt, TupleArgumentsFlag}; +use crate::errors; use crate::type_error_struct; use rustc_ast::util::parser::PREC_POSTFIX; -use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, StashKey}; +use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, StashKey}; use rustc_hir as hir; use rustc_hir::def::{self, CtorKind, DefKind, Namespace, Res}; use rustc_hir::def_id::DefId; @@ -44,23 +45,15 @@ pub fn check_legal_trait_for_method_call( trait_id: DefId, ) { if tcx.lang_items().drop_trait() == Some(trait_id) { - let mut err = struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method"); - err.span_label(span, "explicit destructor calls not allowed"); - - let (sp, suggestion) = receiver - .and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok()) - .filter(|snippet| !snippet.is_empty()) - .map(|snippet| (expr_span, format!("drop({snippet})"))) - .unwrap_or_else(|| (span, "drop".to_string())); - - err.span_suggestion( - sp, - "consider using `drop` function", - suggestion, - Applicability::MaybeIncorrect, - ); - - err.emit(); + let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) { + errors::ExplicitDestructorCallSugg::Snippet { + lo: expr_span.shrink_to_lo(), + hi: receiver.shrink_to_hi().to(expr_span.shrink_to_hi()), + } + } else { + errors::ExplicitDestructorCallSugg::Empty(span) + }; + tcx.sess.emit_err(errors::ExplicitDestructorCall { span, sugg }); } } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 054d23c71d4..8ba04ec4baf 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -129,6 +129,29 @@ pub enum ExpectedReturnTypeLabel<'tcx> { }, } +#[derive(Diagnostic)] +#[diag(hir_typeck_explicit_destructor, code = "E0040")] +pub struct ExplicitDestructorCall { + #[primary_span] + #[label] + pub span: Span, + #[subdiagnostic] + pub sugg: ExplicitDestructorCallSugg, +} + +#[derive(Subdiagnostic)] +pub enum ExplicitDestructorCallSugg { + #[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")] + Empty(#[primary_span] Span), + #[multipart_suggestion(hir_typeck_suggestion, style = "short")] + Snippet { + #[suggestion_part(code = "drop(")] + lo: Span, + #[suggestion_part(code = ")")] + hi: Span, + }, +} + #[derive(Diagnostic)] #[diag(hir_typeck_missing_parentheses_in_range, code = "E0689")] pub struct MissingParenthesesInRange { diff --git a/tests/ui/error-codes/E0040.stderr b/tests/ui/error-codes/E0040.stderr index 9fcda1a9385..839be79d28d 100644 --- a/tests/ui/error-codes/E0040.stderr +++ b/tests/ui/error-codes/E0040.stderr @@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method --> $DIR/E0040.rs:16:7 | LL | x.drop(); - | --^^^^-- - | | | - | | explicit destructor calls not allowed - | help: consider using `drop` function: `drop(x)` + | ^^^^ explicit destructor calls not allowed + | +help: consider using `drop` function + | +LL | drop(x); + | +++++ ~ error: aborting due to previous error diff --git a/tests/ui/explicit/explicit-call-to-dtor.stderr b/tests/ui/explicit/explicit-call-to-dtor.stderr index f3c9bf6cccd..f2e0b73b6c5 100644 --- a/tests/ui/explicit/explicit-call-to-dtor.stderr +++ b/tests/ui/explicit/explicit-call-to-dtor.stderr @@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-dtor.rs:15:7 | LL | x.drop(); - | --^^^^-- - | | | - | | explicit destructor calls not allowed - | help: consider using `drop` function: `drop(x)` + | ^^^^ explicit destructor calls not allowed + | +help: consider using `drop` function + | +LL | drop(x); + | +++++ ~ error: aborting due to previous error diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr index c7067117349..5fa42fcf191 100644 --- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr +++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr @@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-supertrait-dtor.rs:22:14 | LL | self.drop(); - | -----^^^^-- - | | | - | | explicit destructor calls not allowed - | help: consider using `drop` function: `drop(self)` + | ^^^^ explicit destructor calls not allowed + | +help: consider using `drop` function + | +LL | drop(self); + | +++++ ~ error: aborting due to previous error From 9edeb19f9609ba82e4a0401e70dd704abddea4bc Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 15 Sep 2023 01:07:28 +0000 Subject: [PATCH 2/5] Allow internal untranslatable diagnostic --- compiler/rustc_hir_typeck/src/callee.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index c5b2aaf2361..8c47eed05e9 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -380,6 +380,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Unit testing: function items annotated with // `#[rustc_evaluate_where_clauses]` trigger special output // to let us test the trait evaluation system. + // Untranslatable diagnostics are okay for rustc internals + #[allow(rustc::untranslatable_diagnostic)] + #[allow(rustc::diagnostic_outside_of_impl)] if self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) { let predicates = self.tcx.predicates_of(def_id); let predicates = predicates.instantiate(self.tcx, args); From b40f11c8a97bf3d5b607449ed16370047e3e56f4 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 15 Sep 2023 01:10:08 +0000 Subject: [PATCH 3/5] Migrate 'rust-call incorrect arguments' diagnostic --- compiler/rustc_hir_typeck/messages.ftl | 3 +++ compiler/rustc_hir_typeck/src/callee.rs | 7 ++----- compiler/rustc_hir_typeck/src/errors.rs | 7 +++++++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index d12a6a09079..cf041166000 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -90,6 +90,9 @@ hir_typeck_return_stmt_outside_of_fn_body = .encl_body_label = the {$statement_kind} is part of this body... .encl_fn_label = ...not the enclosing function body +hir_typeck_rustcall_incorrect_args = + functions with the "rust-call" ABI must take a single non-self tuple argument + hir_typeck_struct_expr_non_exhaustive = cannot create non-exhaustive {$what} using struct expression diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 8c47eed05e9..6535bc77dcf 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -382,7 +382,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // to let us test the trait evaluation system. // Untranslatable diagnostics are okay for rustc internals #[allow(rustc::untranslatable_diagnostic)] - #[allow(rustc::diagnostic_outside_of_impl)] + #[allow(rustc::diagnostic_outside_of_impl)] if self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) { let predicates = self.tcx.predicates_of(def_id); let predicates = predicates.instantiate(self.tcx, args); @@ -474,10 +474,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); self.require_type_is_sized(ty, sp, traits::RustCall); } else { - self.tcx.sess.span_err( - sp, - "functions with the \"rust-call\" ABI must take a single non-self tuple argument", - ); + self.tcx.sess.emit_err(errors::RustCallIncorrectArgs { span: sp }); } } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 8ba04ec4baf..bcf19c249e7 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -54,6 +54,13 @@ impl IntoDiagnosticArg for ReturnLikeStatementKind { } } +#[derive(Diagnostic)] +#[diag(hir_typeck_rustcall_incorrect_args)] +pub struct RustCallIncorrectArgs { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(hir_typeck_yield_expr_outside_of_generator, code = "E0627")] pub struct YieldExprOutsideOfGenerator { From cb9f666fdf50bf80b71a54ccfcb7dfe4ad4c84d4 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 15 Sep 2023 01:15:47 +0000 Subject: [PATCH 4/5] Migrate 'invalid callee' diagnostic --- compiler/rustc_hir_typeck/messages.ftl | 4 +++- compiler/rustc_hir_typeck/src/callee.rs | 16 +++++++--------- compiler/rustc_hir_typeck/src/errors.rs | 8 ++++++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index cf041166000..33be8b09adf 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -56,8 +56,10 @@ hir_typeck_functional_record_update_on_non_struct = hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml` hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc` -hir_typeck_lang_start_expected_sig_note = the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize` +hir_typeck_invalid_callee = expected function, found {$ty} + +hir_typeck_lang_start_expected_sig_note = the `start` lang item should have the signature `fn(fn() -> T, isize, *const *const u8, u8) -> isize` hir_typeck_lang_start_incorrect_number_params = incorrect number of parameters for the `start` lang item hir_typeck_lang_start_incorrect_number_params_note_expected_count = the `start` lang item should have four parameters, but found {$found_param_count} diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 6535bc77dcf..93e6f4e51d4 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -3,7 +3,6 @@ use super::method::MethodCallee; use super::{Expectation, FnCtxt, TupleArgumentsFlag}; use crate::errors; -use crate::type_error_struct; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, StashKey}; use rustc_hir as hir; @@ -603,17 +602,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } let callee_ty = self.resolve_vars_if_possible(callee_ty); - let mut err = type_error_struct!( - self.tcx.sess, - callee_expr.span, - callee_ty, - E0618, - "expected function, found {}", - match &unit_variant { + let mut err = self.tcx.sess.create_err(errors::InvalidCallee { + span: callee_expr.span, + ty: match &unit_variant { Some((_, kind, path)) => format!("{kind} `{path}`"), None => format!("`{callee_ty}`"), } - ); + }); + if callee_ty.references_error() { + err.downgrade_to_delayed_bug(); + } self.identify_bad_closure_def_and_call( &mut err, diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index bcf19c249e7..28659b74e84 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -282,6 +282,14 @@ impl HelpUseLatestEdition { } } +#[derive(Diagnostic)] +#[diag(hir_typeck_invalid_callee, code = "E0618")] +pub struct InvalidCallee { + #[primary_span] + pub span: Span, + pub ty: String, +} + #[derive(Subdiagnostic)] pub enum OptionResultRefMismatch { #[suggestion( From 8696ee8b0991888c8adc256eb85e5fc1da02b648 Mon Sep 17 00:00:00 2001 From: clubby789 Date: Fri, 15 Sep 2023 01:18:38 +0000 Subject: [PATCH 5/5] Migrate 'missing fn lang items' diagnostic --- compiler/rustc_hir_typeck/messages.ftl | 3 +++ compiler/rustc_hir_typeck/src/callee.rs | 12 ++---------- compiler/rustc_hir_typeck/src/errors.rs | 8 ++++++++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl index 33be8b09adf..f7506879b5d 100644 --- a/compiler/rustc_hir_typeck/messages.ftl +++ b/compiler/rustc_hir_typeck/messages.ftl @@ -72,6 +72,9 @@ hir_typeck_lang_start_incorrect_ret_ty = the return type of the `start` lang ite hir_typeck_method_call_on_unknown_raw_pointee = cannot call a method on a raw pointer with an unknown pointee type +hir_typeck_missing_fn_lang_items = failed to find an overloaded call trait for closure call + .help = make sure the `fn`/`fn_mut`/`fn_once` lang items are defined and have correctly defined `call`/`call_mut`/`call_once` methods + hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}` hir_typeck_no_associated_item = no {$item_kind} named `{$item_name}` found for {$ty_prefix} `{$ty_str}`{$trait_missing_method -> diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index 93e6f4e51d4..b39919ece71 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -607,7 +607,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty: match &unit_variant { Some((_, kind, path)) => format!("{kind} `{path}`"), None => format!("`{callee_ty}`"), - } + }, }); if callee_ty.references_error() { err.downgrade_to_delayed_bug(); @@ -882,15 +882,7 @@ impl<'a, 'tcx> DeferredCallResolution<'tcx> { None => { // This can happen if `#![no_core]` is used and the `fn/fn_mut/fn_once` // lang items are not defined (issue #86238). - let mut err = fcx.inh.tcx.sess.struct_span_err( - self.call_expr.span, - "failed to find an overloaded call trait for closure call", - ); - err.help( - "make sure the `fn`/`fn_mut`/`fn_once` lang items are defined \ - and have correctly defined `call`/`call_mut`/`call_once` methods", - ); - err.emit(); + fcx.inh.tcx.sess.emit_err(errors::MissingFnLangItems { span: self.call_expr.span }); } } } diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs index 28659b74e84..40c0676c8d2 100644 --- a/compiler/rustc_hir_typeck/src/errors.rs +++ b/compiler/rustc_hir_typeck/src/errors.rs @@ -83,6 +83,14 @@ pub struct MethodCallOnUnknownRawPointee { pub span: Span, } +#[derive(Diagnostic)] +#[diag(hir_typeck_missing_fn_lang_items)] +#[help] +pub struct MissingFnLangItems { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(hir_typeck_functional_record_update_on_non_struct, code = "E0436")] pub struct FunctionalRecordUpdateOnNonStruct {