From 34b51187ce8fa261ebe3bef4a9a26135b919ac02 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Wed, 20 May 2020 17:48:21 +0300 Subject: [PATCH 1/3] Suggest using std::mem::drop function instead of explicit destructor call --- src/librustc_typeck/check/callee.rs | 26 ++++++++++++++++--- src/librustc_typeck/check/method/confirm.rs | 9 ++++--- src/librustc_typeck/check/mod.rs | 2 +- src/test/ui/error-codes/E0040.stderr | 5 +++- .../ui/explicit/explicit-call-to-dtor.stderr | 5 +++- .../explicit-call-to-supertrait-dtor.stderr | 5 +++- src/test/ui/illegal-ufcs-drop.stderr | 5 +++- 7 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 52ddacc1c4b1a..4c31363f2c084 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -21,11 +21,29 @@ use rustc_target::spec::abi; /// Checks that it is legal to call methods of the trait corresponding /// to `trait_id` (this only cares about the trait, not the specific /// method that is called). -pub fn check_legal_trait_for_method_call(tcx: TyCtxt<'_>, span: Span, trait_id: DefId) { +pub fn check_legal_trait_for_method_call( + tcx: TyCtxt<'_>, + span: Span, + receiver: Option, + trait_id: DefId, +) { if tcx.lang_items().drop_trait() == Some(trait_id) { - struct_span_err!(tcx.sess, span, E0040, "explicit use of destructor method") - .span_label(span, "explicit destructor calls not allowed") - .emit(); + 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 snippet = receiver + .and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok()) + .unwrap_or_default(); + + let (suggestion, applicability) = if snippet.is_empty() { + (snippet, Applicability::Unspecified) + } else { + (format!("drop({})", snippet), Applicability::MachineApplicable) + }; + + err.span_suggestion(span, "consider using `drop` function", suggestion, applicability); + + err.emit(); } } diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index c4805c54a7d43..38a5bd5fce00d 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -597,9 +597,12 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) { // Disallow calls to the method `drop` defined in the `Drop` trait. match pick.item.container { - ty::TraitContainer(trait_def_id) => { - callee::check_legal_trait_for_method_call(self.tcx, self.span, trait_def_id) - } + ty::TraitContainer(trait_def_id) => callee::check_legal_trait_for_method_call( + self.tcx, + self.span, + Some(self.self_expr.span), + trait_def_id, + ), ty::ImplContainer(..) => {} } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index d72c74e4188ee..3ac3934bea32b 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5438,7 +5438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { debug!("instantiate_value_path: def_id={:?} container={:?}", def_id, container); match container { ty::TraitContainer(trait_did) => { - callee::check_legal_trait_for_method_call(tcx, span, trait_did) + callee::check_legal_trait_for_method_call(tcx, span, None, trait_did) } ty::ImplContainer(impl_def_id) => { if segments.len() == 1 { diff --git a/src/test/ui/error-codes/E0040.stderr b/src/test/ui/error-codes/E0040.stderr index 966455902817d..69cf28b29704f 100644 --- a/src/test/ui/error-codes/E0040.stderr +++ b/src/test/ui/error-codes/E0040.stderr @@ -2,7 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/E0040.rs:13:7 | LL | x.drop(); - | ^^^^ explicit destructor calls not allowed + | ^^^^ + | | + | explicit destructor calls not allowed + | help: consider using `drop` function: `drop(x)` error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-call-to-dtor.stderr b/src/test/ui/explicit/explicit-call-to-dtor.stderr index cbbe967179ef3..5ebe4ee4b90f8 100644 --- a/src/test/ui/explicit/explicit-call-to-dtor.stderr +++ b/src/test/ui/explicit/explicit-call-to-dtor.stderr @@ -2,7 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-dtor.rs:13:7 | LL | x.drop(); - | ^^^^ explicit destructor calls not allowed + | ^^^^ + | | + | explicit destructor calls not allowed + | help: consider using `drop` function: `drop(x)` error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr index 0b302e30b64f3..cd3fb3119a5cf 100644 --- a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr +++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr @@ -2,7 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-supertrait-dtor.rs:17:14 | LL | self.drop(); - | ^^^^ explicit destructor calls not allowed + | ^^^^ + | | + | explicit destructor calls not allowed + | help: consider using `drop` function: `drop(self)` error: aborting due to previous error diff --git a/src/test/ui/illegal-ufcs-drop.stderr b/src/test/ui/illegal-ufcs-drop.stderr index d35d376962c17..922d50d259569 100644 --- a/src/test/ui/illegal-ufcs-drop.stderr +++ b/src/test/ui/illegal-ufcs-drop.stderr @@ -2,7 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/illegal-ufcs-drop.rs:8:5 | LL | Drop::drop(&mut Foo) - | ^^^^^^^^^^ explicit destructor calls not allowed + | ^^^^^^^^^^ + | | + | explicit destructor calls not allowed + | help: consider using `drop` function error: aborting due to previous error From a9199de34d0ad78fe1ff0d072f6bd5c01906bdb3 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Sat, 23 May 2020 00:16:17 +0300 Subject: [PATCH 2/3] Merge spans for the suggestion --- src/librustc_typeck/check/callee.rs | 17 +++++++++++------ src/test/ui/error-codes/E0040.stderr | 8 ++++---- .../ui/explicit/explicit-call-to-dtor.stderr | 8 ++++---- .../explicit-call-to-supertrait-dtor.stderr | 8 ++++---- src/test/ui/illegal-ufcs-drop.stderr | 2 +- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index 4c31363f2c084..a32174a83337d 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -35,13 +35,18 @@ pub fn check_legal_trait_for_method_call( .and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok()) .unwrap_or_default(); - let (suggestion, applicability) = if snippet.is_empty() { - (snippet, Applicability::Unspecified) - } else { - (format!("drop({})", snippet), Applicability::MachineApplicable) - }; + let suggestion = + if snippet.is_empty() { "drop".to_string() } else { format!("drop({})", snippet) }; + + let suggestion_span = + receiver.and_then(|s| tcx.sess.source_map().merge_spans(s, span)).unwrap_or(span); - err.span_suggestion(span, "consider using `drop` function", suggestion, applicability); + err.span_suggestion( + suggestion_span, + "consider using `drop` function", + suggestion, + Applicability::MaybeIncorrect, + ); err.emit(); } diff --git a/src/test/ui/error-codes/E0040.stderr b/src/test/ui/error-codes/E0040.stderr index 69cf28b29704f..3b864d4ea4b2c 100644 --- a/src/test/ui/error-codes/E0040.stderr +++ b/src/test/ui/error-codes/E0040.stderr @@ -2,10 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/E0040.rs:13: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: `drop(x)` error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-call-to-dtor.stderr b/src/test/ui/explicit/explicit-call-to-dtor.stderr index 5ebe4ee4b90f8..33ce235b30fda 100644 --- a/src/test/ui/explicit/explicit-call-to-dtor.stderr +++ b/src/test/ui/explicit/explicit-call-to-dtor.stderr @@ -2,10 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-dtor.rs:13: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: `drop(x)` error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr index cd3fb3119a5cf..2e7bfac71cd32 100644 --- a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr +++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr @@ -2,10 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-supertrait-dtor.rs:17: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: `drop(self)` error: aborting due to previous error diff --git a/src/test/ui/illegal-ufcs-drop.stderr b/src/test/ui/illegal-ufcs-drop.stderr index 922d50d259569..57c99739afd24 100644 --- a/src/test/ui/illegal-ufcs-drop.stderr +++ b/src/test/ui/illegal-ufcs-drop.stderr @@ -5,7 +5,7 @@ LL | Drop::drop(&mut Foo) | ^^^^^^^^^^ | | | explicit destructor calls not allowed - | help: consider using `drop` function + | help: consider using `drop` function: `drop` error: aborting due to previous error From 6ddbef170bf0b79b868088580e28c862b691bff3 Mon Sep 17 00:00:00 2001 From: Stanislav Tkach Date: Tue, 26 May 2020 23:06:46 +0300 Subject: [PATCH 3/3] Simplify suggestion --- src/librustc_typeck/check/callee.rs | 11 ++++------- src/test/ui/error-codes/E0040.stderr | 8 ++++---- src/test/ui/explicit/explicit-call-to-dtor.stderr | 8 ++++---- .../explicit/explicit-call-to-supertrait-dtor.stderr | 8 ++++---- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index a32174a83337d..f4e46a0493151 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -38,14 +38,11 @@ pub fn check_legal_trait_for_method_call( let suggestion = if snippet.is_empty() { "drop".to_string() } else { format!("drop({})", snippet) }; - let suggestion_span = - receiver.and_then(|s| tcx.sess.source_map().merge_spans(s, span)).unwrap_or(span); - err.span_suggestion( - suggestion_span, - "consider using `drop` function", - suggestion, - Applicability::MaybeIncorrect, + span, + &format!("consider using `drop` function: `{}`", suggestion), + String::new(), + Applicability::Unspecified, ); err.emit(); diff --git a/src/test/ui/error-codes/E0040.stderr b/src/test/ui/error-codes/E0040.stderr index 3b864d4ea4b2c..69cf28b29704f 100644 --- a/src/test/ui/error-codes/E0040.stderr +++ b/src/test/ui/error-codes/E0040.stderr @@ -2,10 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/E0040.rs:13: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: `drop(x)` error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-call-to-dtor.stderr b/src/test/ui/explicit/explicit-call-to-dtor.stderr index 33ce235b30fda..5ebe4ee4b90f8 100644 --- a/src/test/ui/explicit/explicit-call-to-dtor.stderr +++ b/src/test/ui/explicit/explicit-call-to-dtor.stderr @@ -2,10 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-dtor.rs:13: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: `drop(x)` error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr index 2e7bfac71cd32..cd3fb3119a5cf 100644 --- a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr +++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr @@ -2,10 +2,10 @@ error[E0040]: explicit use of destructor method --> $DIR/explicit-call-to-supertrait-dtor.rs:17: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: `drop(self)` error: aborting due to previous error