diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs index 116b079e7425a..4836418b3c210 100644 --- a/compiler/rustc_typeck/src/check/callee.rs +++ b/compiler/rustc_typeck/src/check/callee.rs @@ -25,24 +25,24 @@ pub fn check_legal_trait_for_method_call( tcx: TyCtxt<'_>, span: Span, receiver: Option, + expr_span: Span, 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 snippet = receiver + let (sp, suggestion) = receiver .and_then(|s| tcx.sess.source_map().span_to_snippet(s).ok()) - .unwrap_or_default(); - - let suggestion = - if snippet.is_empty() { "drop".to_string() } else { format!("drop({})", snippet) }; + .filter(|snippet| !snippet.is_empty()) + .map(|snippet| (expr_span, format!("drop({})", snippet))) + .unwrap_or_else(|| (span, "drop".to_string())); err.span_suggestion( - span, - &format!("consider using `drop` function: `{}`", suggestion), - String::new(), - Applicability::Unspecified, + sp, + "consider using `drop` function", + suggestion, + Applicability::MaybeIncorrect, ); err.emit(); diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index c491ba3084192..ed48a0bc801cf 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1163,7 +1163,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, None, trait_did) + callee::check_legal_trait_for_method_call(tcx, span, None, span, trait_did) } ty::ImplContainer(impl_def_id) => { if segments.len() == 1 { diff --git a/compiler/rustc_typeck/src/check/method/confirm.rs b/compiler/rustc_typeck/src/check/method/confirm.rs index 97c9620eb16c3..e5f19281b0773 100644 --- a/compiler/rustc_typeck/src/check/method/confirm.rs +++ b/compiler/rustc_typeck/src/check/method/confirm.rs @@ -508,6 +508,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> { self.tcx, self.span, Some(self.self_expr.span), + self.call_expr.span, trait_def_id, ), ty::ImplContainer(..) => {} diff --git a/src/test/ui/error-codes/E0040.fixed b/src/test/ui/error-codes/E0040.fixed new file mode 100644 index 0000000000000..139dc8f94964f --- /dev/null +++ b/src/test/ui/error-codes/E0040.fixed @@ -0,0 +1,18 @@ +// run-rustfix +struct Foo { + x: i32, +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("kaboom"); + } +} + +fn main() { + let mut x = Foo { x: -7 }; + x.x = 0; + println!("{}", x.x); + drop(x); + //~^ ERROR E0040 +} diff --git a/src/test/ui/error-codes/E0040.rs b/src/test/ui/error-codes/E0040.rs index 113efae82c510..9ffc42d0c7804 100644 --- a/src/test/ui/error-codes/E0040.rs +++ b/src/test/ui/error-codes/E0040.rs @@ -1,3 +1,4 @@ +// run-rustfix struct Foo { x: i32, } @@ -10,6 +11,8 @@ impl Drop for Foo { fn main() { let mut x = Foo { x: -7 }; + x.x = 0; + println!("{}", x.x); x.drop(); //~^ ERROR E0040 } diff --git a/src/test/ui/error-codes/E0040.stderr b/src/test/ui/error-codes/E0040.stderr index 69cf28b29704f..9fcda1a9385d2 100644 --- a/src/test/ui/error-codes/E0040.stderr +++ b/src/test/ui/error-codes/E0040.stderr @@ -1,11 +1,11 @@ error[E0040]: explicit use of destructor method - --> $DIR/E0040.rs:13:7 + --> $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: `drop(x)` error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-call-to-dtor.fixed b/src/test/ui/explicit/explicit-call-to-dtor.fixed new file mode 100644 index 0000000000000..91a4ca608da4e --- /dev/null +++ b/src/test/ui/explicit/explicit-call-to-dtor.fixed @@ -0,0 +1,16 @@ +// run-rustfix +struct Foo { + x: isize +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("kaboom"); + } +} + +fn main() { + let x = Foo { x: 3 }; + println!("{}", x.x); + drop(x); //~ ERROR explicit use of destructor method +} diff --git a/src/test/ui/explicit/explicit-call-to-dtor.rs b/src/test/ui/explicit/explicit-call-to-dtor.rs index a6f9acc37a16d..0656871eb1b34 100644 --- a/src/test/ui/explicit/explicit-call-to-dtor.rs +++ b/src/test/ui/explicit/explicit-call-to-dtor.rs @@ -1,3 +1,4 @@ +// run-rustfix struct Foo { x: isize } @@ -10,5 +11,6 @@ impl Drop for Foo { fn main() { let x = Foo { x: 3 }; + println!("{}", x.x); x.drop(); //~ ERROR explicit use of destructor method } diff --git a/src/test/ui/explicit/explicit-call-to-dtor.stderr b/src/test/ui/explicit/explicit-call-to-dtor.stderr index 5ebe4ee4b90f8..f3c9bf6cccdd3 100644 --- a/src/test/ui/explicit/explicit-call-to-dtor.stderr +++ b/src/test/ui/explicit/explicit-call-to-dtor.stderr @@ -1,11 +1,11 @@ error[E0040]: explicit use of destructor method - --> $DIR/explicit-call-to-dtor.rs:13:7 + --> $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: `drop(x)` error: aborting due to previous error diff --git a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.fixed b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.fixed new file mode 100644 index 0000000000000..47c4c9f67b692 --- /dev/null +++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.fixed @@ -0,0 +1,26 @@ +// run-rustfix +struct Foo { + x: isize +} + +#[allow(drop_bounds)] +trait Bar: Drop { + fn blah(&self); +} + +impl Drop for Foo { + fn drop(&mut self) { + println!("kaboom"); + } +} + +impl Bar for Foo { + fn blah(&self) { + drop(self); //~ ERROR explicit use of destructor method + } +} + +fn main() { + let x = Foo { x: 3 }; + println!("{}", x.x); +} diff --git a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs index ff56b9a8ae424..c698de50c75b8 100644 --- a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs +++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.rs @@ -1,8 +1,10 @@ +// run-rustfix struct Foo { x: isize } -trait Bar : Drop { +#[allow(drop_bounds)] +trait Bar: Drop { fn blah(&self); } @@ -20,4 +22,5 @@ impl Bar for Foo { fn main() { let x = Foo { x: 3 }; + println!("{}", x.x); } 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..7f5106eb57e54 100644 --- a/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr +++ b/src/test/ui/explicit/explicit-call-to-supertrait-dtor.stderr @@ -1,11 +1,11 @@ error[E0040]: explicit use of destructor method - --> $DIR/explicit-call-to-supertrait-dtor.rs:17:14 + --> $DIR/explicit-call-to-supertrait-dtor.rs:19: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.fixed b/src/test/ui/illegal-ufcs-drop.fixed new file mode 100644 index 0000000000000..d73b391be0621 --- /dev/null +++ b/src/test/ui/illegal-ufcs-drop.fixed @@ -0,0 +1,10 @@ +// run-rustfix +struct Foo; + +impl Drop for Foo { + fn drop(&mut self) {} +} + +fn main() { + drop(&mut Foo) //~ ERROR explicit use of destructor method +} diff --git a/src/test/ui/illegal-ufcs-drop.rs b/src/test/ui/illegal-ufcs-drop.rs index 5c072663eda45..11411f55494c5 100644 --- a/src/test/ui/illegal-ufcs-drop.rs +++ b/src/test/ui/illegal-ufcs-drop.rs @@ -1,3 +1,4 @@ +// run-rustfix struct Foo; impl Drop for Foo { diff --git a/src/test/ui/illegal-ufcs-drop.stderr b/src/test/ui/illegal-ufcs-drop.stderr index 57c99739afd24..91f47d5e456d3 100644 --- a/src/test/ui/illegal-ufcs-drop.stderr +++ b/src/test/ui/illegal-ufcs-drop.stderr @@ -1,5 +1,5 @@ error[E0040]: explicit use of destructor method - --> $DIR/illegal-ufcs-drop.rs:8:5 + --> $DIR/illegal-ufcs-drop.rs:9:5 | LL | Drop::drop(&mut Foo) | ^^^^^^^^^^