about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs48
-rw-r--r--compiler/rustc_lint/src/context.rs10
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs1
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs64
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs58
5 files changed, 64 insertions, 117 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 1a4f0a26f2b..8c6d2eac51e 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -47,7 +47,7 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{struct_span_err, Applicability};
+use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace, PartialRes, PerNS, Res};
 use rustc_hir::def_id::{DefId, DefPathHash, LocalDefId, CRATE_DEF_ID};
@@ -56,11 +56,9 @@ use rustc_hir::intravisit;
 use rustc_hir::{ConstArg, GenericArg, InferKind, ParamName};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_query_system::ich::StableHashingContext;
-use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
-use rustc_session::lint::{BuiltinLintDiagnostics, LintBuffer};
+use rustc_session::lint::LintBuffer;
 use rustc_session::utils::{FlattenNonterminals, NtToTokenstream};
 use rustc_session::Session;
-use rustc_span::edition::Edition;
 use rustc_span::hygiene::ExpnId;
 use rustc_span::source_map::{respan, DesugaringKind};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -1190,11 +1188,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> hir::Ty<'hir> {
         let id = self.lower_node_id(t.id);
         let qpath = self.lower_qpath(t.id, qself, path, param_mode, itctx);
-        let ty = self.ty_path(id, t.span, qpath);
-        if let hir::TyKind::TraitObject(..) = ty.kind {
-            self.maybe_lint_bare_trait(t.span, t.id, qself.is_none() && path.is_global());
-        }
-        ty
+        self.ty_path(id, t.span, qpath)
     }
 
     fn ty(&mut self, span: Span, kind: hir::TyKind<'hir>) -> hir::Ty<'hir> {
@@ -1291,9 +1285,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                         lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span));
                     (bounds, lifetime_bound)
                 });
-                if kind != TraitObjectSyntax::Dyn {
-                    self.maybe_lint_bare_trait(t.span, t.id, false);
-                }
                 hir::TyKind::TraitObject(bounds, lifetime_bound, kind)
             }
             TyKind::ImplTrait(def_node_id, ref bounds) => {
@@ -2395,39 +2386,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             name: hir::LifetimeName::Implicit(missing),
         }
     }
-
-    fn maybe_lint_bare_trait(&mut self, span: Span, id: NodeId, is_global: bool) {
-        // FIXME(davidtwco): This is a hack to detect macros which produce spans of the
-        // call site which do not have a macro backtrace. See #61963.
-        let is_macro_callsite = self
-            .sess
-            .source_map()
-            .span_to_snippet(span)
-            .map(|snippet| snippet.starts_with("#["))
-            .unwrap_or(true);
-        if !is_macro_callsite {
-            if span.edition() < Edition::Edition2021 {
-                self.resolver.lint_buffer().buffer_lint_with_diagnostic(
-                    BARE_TRAIT_OBJECTS,
-                    id,
-                    span,
-                    "trait objects without an explicit `dyn` are deprecated",
-                    BuiltinLintDiagnostics::BareTraitObject(span, is_global),
-                )
-            } else {
-                let msg = "trait objects must include the `dyn` keyword";
-                let label = "add `dyn` keyword before this trait";
-                let mut err = struct_span_err!(self.sess, span, E0782, "{}", msg,);
-                err.span_suggestion_verbose(
-                    span.shrink_to_lo(),
-                    label,
-                    String::from("dyn "),
-                    Applicability::MachineApplicable,
-                );
-                err.emit();
-            }
-        }
-    }
 }
 
 /// Helper struct for delayed construction of GenericArgs.
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 4c936dec6f2..d434549ed85 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -635,16 +635,6 @@ pub trait LintContext: Sized {
                     }
                 },
                 BuiltinLintDiagnostics::Normal => (),
-                BuiltinLintDiagnostics::BareTraitObject(span, is_global) => {
-                    let (sugg, app) = match sess.source_map().span_to_snippet(span) {
-                        Ok(s) if is_global => {
-                            (format!("dyn ({})", s), Applicability::MachineApplicable)
-                        }
-                        Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
-                        Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
-                    };
-                    db.span_suggestion(span, "use `dyn`", sugg, app);
-                }
                 BuiltinLintDiagnostics::AbsPathWithModule(span) => {
                     let (sugg, app) = match sess.source_map().span_to_snippet(span) {
                         Ok(ref s) => {
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index feac2a7cfa4..efc0cecb824 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -285,7 +285,6 @@ pub enum ExternDepSpec {
 #[derive(PartialEq, Debug)]
 pub enum BuiltinLintDiagnostics {
     Normal,
-    BareTraitObject(Span, /* is_global */ bool),
     AbsPathWithModule(Span),
     ProcMacroDeriveResolutionFallback(Span),
     MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index da751f20753..bc271fac68f 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -13,6 +13,7 @@ use crate::errors::{
 };
 use crate::middle::resolve_lifetime as rl;
 use crate::require_c_abi_if_c_variadic;
+use rustc_ast::TraitObjectSyntax;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{struct_span_err, Applicability, ErrorReported, FatalError};
 use rustc_hir as hir;
@@ -24,7 +25,8 @@ use rustc_hir::{GenericArg, GenericArgs};
 use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, Subst, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, Const, DefIdTree, Ty, TyCtxt, TypeFoldable};
-use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
+use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
+use rustc_span::edition::Edition;
 use rustc_span::lev_distance::find_best_match_for_name;
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
@@ -2289,13 +2291,19 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     /// Parses the programmer's textual representation of a type into our
     /// internal notion of a type.
     pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
-        self.ast_ty_to_ty_inner(ast_ty, false)
+        self.ast_ty_to_ty_inner(ast_ty, false, false)
+    }
+
+    /// Parses the programmer's textual representation of a type into our
+    /// internal notion of a type.  This is meant to be used within a path.
+    pub fn ast_ty_to_ty_in_path(&self, ast_ty: &hir::Ty<'_>) -> Ty<'tcx> {
+        self.ast_ty_to_ty_inner(ast_ty, false, true)
     }
 
     /// Turns a `hir::Ty` into a `Ty`. For diagnostics' purposes we keep track of whether trait
     /// objects are borrowed like `&dyn Trait` to avoid emitting redundant errors.
     #[tracing::instrument(level = "debug", skip(self))]
-    fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool) -> Ty<'tcx> {
+    fn ast_ty_to_ty_inner(&self, ast_ty: &hir::Ty<'_>, borrowed: bool, in_path: bool) -> Ty<'tcx> {
         let tcx = self.tcx();
 
         let result_ty = match ast_ty.kind {
@@ -2306,7 +2314,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             hir::TyKind::Rptr(ref region, ref mt) => {
                 let r = self.ast_region_to_region(region, None);
                 debug!(?r);
-                let t = self.ast_ty_to_ty_inner(mt.ty, true);
+                let t = self.ast_ty_to_ty_inner(mt.ty, true, false);
                 tcx.mk_ref(r, ty::TypeAndMut { ty: t, mutbl: mt.mutbl })
             }
             hir::TyKind::Never => tcx.types.never,
@@ -2325,6 +2333,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 ))
             }
             hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
+                self.maybe_lint_bare_trait(ast_ty, in_path);
                 self.conv_object_ty_poly_trait_ref(ast_ty.span, bounds, lifetime, borrowed)
             }
             hir::TyKind::Path(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
@@ -2345,7 +2354,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
             hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => {
                 debug!(?qself, ?segment);
-                let ty = self.ast_ty_to_ty(qself);
+                let ty = self.ast_ty_to_ty_inner(qself, false, true);
 
                 let res = if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = qself.kind {
                     path.res
@@ -2602,4 +2611,49 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         }
         Some(r)
     }
+
+    fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
+        let tcx = self.tcx();
+        if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
+            self_ty.kind
+        {
+            let (mut sugg, app) = match tcx.sess.source_map().span_to_snippet(self_ty.span) {
+                Ok(s) if poly_trait_ref.trait_ref.path.is_global() => {
+                    (format!("dyn ({})", s), Applicability::MachineApplicable)
+                }
+                Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
+                Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
+            };
+            if in_path {
+                let has_bracket = tcx
+                    .sess
+                    .source_map()
+                    .span_to_prev_source(self_ty.span)
+                    .ok()
+                    .map_or(false, |s| s.trim_end().ends_with('<'));
+                if !has_bracket {
+                    sugg = format!("<{}>", sugg);
+                }
+            }
+            if tcx.sess.edition() >= Edition::Edition2021 {
+                let msg = "trait objects must include the `dyn` keyword";
+                let label = "add `dyn` keyword before this trait";
+                let mut err =
+                    rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg);
+                err.span_suggestion_verbose(self_ty.span, label, sugg, app).emit();
+            } else {
+                let msg = "trait objects without an explicit `dyn` are deprecated";
+                tcx.struct_span_lint_hir(
+                    BARE_TRAIT_OBJECTS,
+                    self_ty.hir_id,
+                    self_ty.span,
+                    |lint| {
+                        let mut db = lint.build(msg);
+                        db.span_suggestion(self_ty.span, "use `dyn`", sugg, app);
+                        db.emit()
+                    },
+                );
+            }
+        }
+    }
 }
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index a02a7d7cbfe..66546b36aa1 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -6,7 +6,6 @@ use crate::check::callee::{self, DeferredCallResolution};
 use crate::check::method::{self, MethodCallee, SelfSource};
 use crate::check::{BreakableCtxt, Diverges, Expectation, FnCtxt, LocalTy};
 
-use rustc_ast::TraitObjectSyntax;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{Applicability, DiagnosticBuilder, ErrorReported};
@@ -14,7 +13,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{ExprKind, GenericArg, Node, QPath, TyKind};
+use rustc_hir::{ExprKind, GenericArg, Node, QPath};
 use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
 use rustc_infer::infer::error_reporting::TypeAnnotationNeeded::E0282;
 use rustc_infer::infer::{InferOk, InferResult};
@@ -28,8 +27,6 @@ use rustc_middle::ty::{
     Ty, UserType,
 };
 use rustc_session::lint;
-use rustc_session::lint::builtin::BARE_TRAIT_OBJECTS;
-use rustc_span::edition::Edition;
 use rustc_span::hygiene::DesugaringKind;
 use rustc_span::source_map::{original_sp, DUMMY_SP};
 use rustc_span::symbol::{kw, sym, Ident};
@@ -844,7 +841,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // to be object-safe.
                 // We manually call `register_wf_obligation` in the success path
                 // below.
-                (<dyn AstConv<'_>>::ast_ty_to_ty(self, qself), qself, segment)
+                (<dyn AstConv<'_>>::ast_ty_to_ty_in_path(self, qself), qself, segment)
             }
             QPath::LangItem(..) => {
                 bug!("`resolve_ty_and_res_fully_qualified_call` called on `LangItem`")
@@ -890,7 +887,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             });
 
         if result.is_ok() {
-            self.maybe_lint_bare_trait(qpath, hir_id, span);
             self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
         }
 
@@ -903,56 +899,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         )
     }
 
-    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
-            {
-                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!("dyn ({})", s), Applicability::MachineApplicable)
-                    }
-                    Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
-                    Err(_) => ("dyn <type>".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 sugg_label = "use `dyn`";
-                if self.sess().edition() >= Edition::Edition2021 {
-                    let mut err = rustc_errors::struct_span_err!(
-                        self.sess(),
-                        self_ty.span,
-                        E0782,
-                        "{}",
-                        msg,
-                    );
-                    err.span_suggestion(
-                        self_ty.span,
-                        sugg_label,
-                        sugg,
-                        Applicability::MachineApplicable,
-                    )
-                    .emit();
-                } else {
-                    self.tcx.struct_span_lint_hir(
-                        BARE_TRAIT_OBJECTS,
-                        hir_id,
-                        self_ty.span,
-                        |lint| {
-                            let mut db = lint.build(msg);
-                            db.span_suggestion(self_ty.span, sugg_label, sugg, app);
-                            db.emit()
-                        },
-                    );
-                }
-            }
-        }
-    }
-
     /// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
     pub(in super::super) fn get_node_fn_decl(
         &self,