diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 25d1c8706e874..17e0c42440c21 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -914,7 +914,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }); if result.is_ok() { - self.maybe_lint_bare_trait(qpath, hir_id); + self.maybe_lint_bare_trait(qpath, hir_id, span); self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None)); } @@ -927,7 +927,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } - fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId) { + fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId, span: Span) { if let QPath::TypeRelative(self_ty, _) = qpath { if let TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) = self_ty.kind @@ -935,10 +935,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let msg = "trait objects without an explicit `dyn` are deprecated"; let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(self_ty.span) { Ok(s) if poly_trait_ref.trait_ref.path.is_global() => { - (format!("", s), Applicability::MachineApplicable) + (format!("dyn ({})", s), Applicability::MachineApplicable) } - Ok(s) => (format!("", s), Applicability::MachineApplicable), - Err(_) => (">".to_string(), Applicability::HasPlaceholders), + Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable), + Err(_) => ("dyn ".to_string(), Applicability::HasPlaceholders), + }; + // Wrap in `<..>` if it isn't already. + let sugg = match self.tcx.sess.source_map().span_to_snippet(span) { + Ok(s) if s.starts_with('<') => sugg, + _ => format!("<{}>", sugg), }; let replace = String::from("use `dyn`"); if self.sess().edition() >= Edition::Edition2021 { diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed b/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed new file mode 100644 index 0000000000000..25caa6a8030ff --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed @@ -0,0 +1,23 @@ +// See https://github.com/rust-lang/rust/issues/88508 +// run-rustfix +// edition:2018 +#![deny(bare_trait_objects)] +#![allow(dead_code)] +#![allow(unused_imports)] + +use std::fmt; + +#[derive(Debug)] +pub struct Foo; + +impl fmt::Display for Foo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::fmt(self, f) + //~^ ERROR trait objects without an explicit `dyn` are deprecated + //~| WARNING this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated + //~| WARNING this is accepted in the current edition + } +} + +fn main() {} diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.rs b/src/test/ui/dyn-keyword/dyn-angle-brackets.rs new file mode 100644 index 0000000000000..cf72da2b61ec2 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.rs @@ -0,0 +1,23 @@ +// See https://github.com/rust-lang/rust/issues/88508 +// run-rustfix +// edition:2018 +#![deny(bare_trait_objects)] +#![allow(dead_code)] +#![allow(unused_imports)] + +use std::fmt; + +#[derive(Debug)] +pub struct Foo; + +impl fmt::Display for Foo { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + ::fmt(self, f) + //~^ ERROR trait objects without an explicit `dyn` are deprecated + //~| WARNING this is accepted in the current edition + //~| ERROR trait objects without an explicit `dyn` are deprecated + //~| WARNING this is accepted in the current edition + } +} + +fn main() {} diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr new file mode 100644 index 0000000000000..ef0f5b7f59db9 --- /dev/null +++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr @@ -0,0 +1,25 @@ +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-angle-brackets.rs:15:10 + | +LL | ::fmt(self, f) + | ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Debug` + | +note: the lint level is defined here + --> $DIR/dyn-angle-brackets.rs:4:9 + | +LL | #![deny(bare_trait_objects)] + | ^^^^^^^^^^^^^^^^^^ + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see + +error: trait objects without an explicit `dyn` are deprecated + --> $DIR/dyn-angle-brackets.rs:15:10 + | +LL | ::fmt(self, f) + | ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Debug` + | + = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021! + = note: for more information, see + +error: aborting due to 2 previous errors +