Skip to content

Commit 6e2adbf

Browse files
committed
Migrate 'explicit destructor call' diagnostic
1 parent ca2b74f commit 6e2adbf

File tree

6 files changed

+56
-30
lines changed

6 files changed

+56
-30
lines changed

compiler/rustc_hir_typeck/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ hir_typeck_expected_default_return_type = expected `()` because of default retur
3333
3434
hir_typeck_expected_return_type = expected `{$expected}` because of return type
3535
36+
hir_typeck_explicit_destructor = explicit use of destructor method
37+
.label = explicit destructor calls not allowed
38+
.suggestion = consider using `drop` function
39+
3640
hir_typeck_field_multiply_specified_in_initializer =
3741
field `{$ident}` specified more than once
3842
.label = used more than once

compiler/rustc_hir_typeck/src/callee.rs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ use super::method::probe::ProbeScope;
22
use super::method::MethodCallee;
33
use super::{Expectation, FnCtxt, TupleArgumentsFlag};
44

5+
use crate::errors;
56
use crate::type_error_struct;
67
use rustc_ast::util::parser::PREC_POSTFIX;
7-
use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorGuaranteed, StashKey};
8+
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, StashKey};
89
use rustc_hir as hir;
910
use rustc_hir::def::{self, CtorKind, DefKind, Namespace, Res};
1011
use rustc_hir::def_id::DefId;
@@ -44,23 +45,15 @@ pub fn check_legal_trait_for_method_call(
4445
trait_id: DefId,
4546
) {
4647
if tcx.lang_items().drop_trait() == Some(trait_id) {
47-
let mut err = struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method");
48-
err.span_label(span, "explicit destructor calls not allowed");
49-
50-
let (sp, suggestion) = receiver
51-
.and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok())
52-
.filter(|snippet| !snippet.is_empty())
53-
.map(|snippet| (expr_span, format!("drop({snippet})")))
54-
.unwrap_or_else(|| (span, "drop".to_string()));
55-
56-
err.span_suggestion(
57-
sp,
58-
"consider using `drop` function",
59-
suggestion,
60-
Applicability::MaybeIncorrect,
61-
);
62-
63-
err.emit();
48+
let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {
49+
errors::ExplicitDestructorCallSugg::Snippet {
50+
lo: expr_span.shrink_to_lo(),
51+
hi: receiver.shrink_to_hi().to(expr_span.shrink_to_hi()),
52+
}
53+
} else {
54+
errors::ExplicitDestructorCallSugg::Empty(span)
55+
};
56+
tcx.sess.emit_err(errors::ExplicitDestructorCall { span, sugg });
6457
}
6558
}
6659

compiler/rustc_hir_typeck/src/errors.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,29 @@ pub enum ExpectedReturnTypeLabel<'tcx> {
129129
},
130130
}
131131

132+
#[derive(Diagnostic)]
133+
#[diag(hir_typeck_explicit_destructor, code = "E0040")]
134+
pub struct ExplicitDestructorCall {
135+
#[primary_span]
136+
#[label]
137+
pub span: Span,
138+
#[subdiagnostic]
139+
pub sugg: ExplicitDestructorCallSugg,
140+
}
141+
142+
#[derive(Subdiagnostic)]
143+
pub enum ExplicitDestructorCallSugg {
144+
#[suggestion(hir_typeck_suggestion, code = "drop", applicability = "maybe-incorrect")]
145+
Empty(#[primary_span] Span),
146+
#[multipart_suggestion(hir_typeck_suggestion, style = "short")]
147+
Snippet {
148+
#[suggestion_part(code = "drop(")]
149+
lo: Span,
150+
#[suggestion_part(code = ")")]
151+
hi: Span,
152+
},
153+
}
154+
132155
#[derive(Diagnostic)]
133156
#[diag(hir_typeck_missing_parentheses_in_range, code = "E0689")]
134157
pub struct MissingParenthesesInRange {

tests/ui/error-codes/E0040.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method
22
--> $DIR/E0040.rs:16:7
33
|
44
LL | x.drop();
5-
| --^^^^--
6-
| | |
7-
| | explicit destructor calls not allowed
8-
| help: consider using `drop` function: `drop(x)`
5+
| ^^^^ explicit destructor calls not allowed
6+
|
7+
help: consider using `drop` function
8+
|
9+
LL | drop(x);
10+
| +++++ ~
911

1012
error: aborting due to previous error
1113

tests/ui/explicit/explicit-call-to-dtor.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method
22
--> $DIR/explicit-call-to-dtor.rs:15:7
33
|
44
LL | x.drop();
5-
| --^^^^--
6-
| | |
7-
| | explicit destructor calls not allowed
8-
| help: consider using `drop` function: `drop(x)`
5+
| ^^^^ explicit destructor calls not allowed
6+
|
7+
help: consider using `drop` function
8+
|
9+
LL | drop(x);
10+
| +++++ ~
911

1012
error: aborting due to previous error
1113

tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ error[E0040]: explicit use of destructor method
22
--> $DIR/explicit-call-to-supertrait-dtor.rs:22:14
33
|
44
LL | self.drop();
5-
| -----^^^^--
6-
| | |
7-
| | explicit destructor calls not allowed
8-
| help: consider using `drop` function: `drop(self)`
5+
| ^^^^ explicit destructor calls not allowed
6+
|
7+
help: consider using `drop` function
8+
|
9+
LL | drop(self);
10+
| +++++ ~
911

1012
error: aborting due to previous error
1113

0 commit comments

Comments
 (0)