about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/lint.rs124
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs120
2 files changed, 128 insertions, 116 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
new file mode 100644
index 00000000000..05a3ab63d5c
--- /dev/null
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -0,0 +1,124 @@
+use rustc_ast::TraitObjectSyntax;
+use rustc_errors::{Diagnostic, StashKey};
+use rustc_hir as hir;
+use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
+use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
+
+use super::AstConv;
+
+impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
+    /// Make sure that we are in the condition to suggest the blanket implementation.
+    pub(super) fn maybe_lint_blanket_trait_impl(
+        &self,
+        self_ty: &hir::Ty<'_>,
+        diag: &mut Diagnostic,
+    ) {
+        let tcx = self.tcx();
+        let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
+        if let hir::Node::Item(hir::Item {
+            kind:
+                hir::ItemKind::Impl(hir::Impl {
+                    self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, ..
+                }),
+            ..
+        }) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
+        {
+            if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
+                return;
+            }
+            let of_trait_span = of_trait_ref.path.span;
+            // make sure that we are not calling unwrap to abort during the compilation
+            let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; };
+            let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; };
+            // check if the trait has generics, to make a correct suggestion
+            let param_name = generics.params.next_type_param_name(None);
+
+            let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() {
+                (span, format!(", {}: {}", param_name, impl_trait_name))
+            } else {
+                (generics.span, format!("<{}: {}>", param_name, impl_trait_name))
+            };
+            diag.multipart_suggestion(
+            format!("alternatively use a blanket \
+                     implementation to implement `{of_trait_name}` for \
+                     all types that also implement `{impl_trait_name}`"),
+                vec![
+                    (self_ty.span, param_name),
+                    add_generic_sugg,
+                ],
+                Applicability::MaybeIncorrect,
+            );
+        }
+    }
+
+    pub(super) 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 needs_bracket = in_path
+                && !tcx
+                    .sess
+                    .source_map()
+                    .span_to_prev_source(self_ty.span)
+                    .ok()
+                    .is_some_and(|s| s.trim_end().ends_with('<'));
+
+            let is_global = poly_trait_ref.trait_ref.path.is_global();
+
+            let mut sugg = Vec::from_iter([(
+                self_ty.span.shrink_to_lo(),
+                format!(
+                    "{}dyn {}",
+                    if needs_bracket { "<" } else { "" },
+                    if is_global { "(" } else { "" },
+                ),
+            )]);
+
+            if is_global || needs_bracket {
+                sugg.push((
+                    self_ty.span.shrink_to_hi(),
+                    format!(
+                        "{}{}",
+                        if is_global { ")" } else { "" },
+                        if needs_bracket { ">" } else { "" },
+                    ),
+                ));
+            }
+
+            if self_ty.span.edition().rust_2021() {
+                let msg = "trait objects must include the `dyn` keyword";
+                let label = "add `dyn` keyword before this trait";
+                let mut diag =
+                    rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg);
+                if self_ty.span.can_be_used_for_suggestions() {
+                    diag.multipart_suggestion_verbose(
+                        label,
+                        sugg,
+                        Applicability::MachineApplicable,
+                    );
+                }
+                // check if the impl trait that we are considering is a impl of a local trait
+                self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
+                diag.stash(self_ty.span, StashKey::TraitMissingMethod);
+            } 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,
+                    msg,
+                    |lint| {
+                        lint.multipart_suggestion_verbose(
+                            "use `dyn`",
+                            sugg,
+                            Applicability::MachineApplicable,
+                        );
+                        self.maybe_lint_blanket_trait_impl(&self_ty, lint);
+                        lint
+                    },
+                );
+            }
+        }
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 8afa0a46d32..221c7ce4f6f 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -4,6 +4,7 @@
 
 mod errors;
 pub mod generics;
+mod lint;
 
 use crate::astconv::errors::prohibit_assoc_ty_binding;
 use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generic_args};
@@ -19,7 +20,7 @@ use rustc_ast::TraitObjectSyntax;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::{
     struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError,
-    MultiSpan, StashKey,
+    MultiSpan,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@@ -33,14 +34,12 @@ use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
 use rustc_middle::ty::GenericParamDefKind;
 use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{DynKind, ToPredicate};
-use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
+use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::symbol::{kw, Ident, Symbol};
 use rustc_span::{sym, Span, DUMMY_SP};
 use rustc_target::spec::abi;
-use rustc_trait_selection::traits::error_reporting::{
-    report_object_safety_error, suggestions::NextTypeParamName,
-};
+use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
 use rustc_trait_selection::traits::wf::object_region_bounds;
 use rustc_trait_selection::traits::{
     self, astconv_object_safety_violations, NormalizeExt, ObligationCtxt,
@@ -3715,115 +3714,4 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         }
         Some(r)
     }
-
-    /// Make sure that we are in the condition to suggest the blanket implementation.
-    fn maybe_lint_blanket_trait_impl(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) {
-        let tcx = self.tcx();
-        let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
-        if let hir::Node::Item(hir::Item {
-            kind:
-                hir::ItemKind::Impl(hir::Impl {
-                    self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, ..
-                }),
-            ..
-        }) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
-        {
-            if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
-                return;
-            }
-            let of_trait_span = of_trait_ref.path.span;
-            // make sure that we are not calling unwrap to abort during the compilation
-            let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; };
-            let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; };
-            // check if the trait has generics, to make a correct suggestion
-            let param_name = generics.params.next_type_param_name(None);
-
-            let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() {
-                (span, format!(", {}: {}", param_name, impl_trait_name))
-            } else {
-                (generics.span, format!("<{}: {}>", param_name, impl_trait_name))
-            };
-            diag.multipart_suggestion(
-            format!("alternatively use a blanket \
-                     implementation to implement `{of_trait_name}` for \
-                     all types that also implement `{impl_trait_name}`"),
-                vec![
-                    (self_ty.span, param_name),
-                    add_generic_sugg,
-                ],
-                Applicability::MaybeIncorrect,
-            );
-        }
-    }
-
-    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 needs_bracket = in_path
-                && !tcx
-                    .sess
-                    .source_map()
-                    .span_to_prev_source(self_ty.span)
-                    .ok()
-                    .is_some_and(|s| s.trim_end().ends_with('<'));
-
-            let is_global = poly_trait_ref.trait_ref.path.is_global();
-
-            let mut sugg = Vec::from_iter([(
-                self_ty.span.shrink_to_lo(),
-                format!(
-                    "{}dyn {}",
-                    if needs_bracket { "<" } else { "" },
-                    if is_global { "(" } else { "" },
-                ),
-            )]);
-
-            if is_global || needs_bracket {
-                sugg.push((
-                    self_ty.span.shrink_to_hi(),
-                    format!(
-                        "{}{}",
-                        if is_global { ")" } else { "" },
-                        if needs_bracket { ">" } else { "" },
-                    ),
-                ));
-            }
-
-            if self_ty.span.edition().rust_2021() {
-                let msg = "trait objects must include the `dyn` keyword";
-                let label = "add `dyn` keyword before this trait";
-                let mut diag =
-                    rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg);
-                if self_ty.span.can_be_used_for_suggestions() {
-                    diag.multipart_suggestion_verbose(
-                        label,
-                        sugg,
-                        Applicability::MachineApplicable,
-                    );
-                }
-                // check if the impl trait that we are considering is a impl of a local trait
-                self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
-                diag.stash(self_ty.span, StashKey::TraitMissingMethod);
-            } 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,
-                    msg,
-                    |lint| {
-                        lint.multipart_suggestion_verbose(
-                            "use `dyn`",
-                            sugg,
-                            Applicability::MachineApplicable,
-                        );
-                        self.maybe_lint_blanket_trait_impl(&self_ty, lint);
-                        lint
-                    },
-                );
-            }
-        }
-    }
 }