Skip to content

Commit 79c2c98

Browse files
committed
Pacify tidy
1 parent f3b7dd6 commit 79c2c98

File tree

2 files changed

+128
-116
lines changed

2 files changed

+128
-116
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
use rustc_ast::TraitObjectSyntax;
2+
use rustc_errors::{Diagnostic, StashKey};
3+
use rustc_hir as hir;
4+
use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
5+
use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamName;
6+
7+
use super::AstConv;
8+
9+
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
10+
/// Make sure that we are in the condition to suggest the blanket implementation.
11+
pub(super) fn maybe_lint_blanket_trait_impl(
12+
&self,
13+
self_ty: &hir::Ty<'_>,
14+
diag: &mut Diagnostic,
15+
) {
16+
let tcx = self.tcx();
17+
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
18+
if let hir::Node::Item(hir::Item {
19+
kind:
20+
hir::ItemKind::Impl(hir::Impl {
21+
self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, ..
22+
}),
23+
..
24+
}) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
25+
{
26+
if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
27+
return;
28+
}
29+
let of_trait_span = of_trait_ref.path.span;
30+
// make sure that we are not calling unwrap to abort during the compilation
31+
let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; };
32+
let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; };
33+
// check if the trait has generics, to make a correct suggestion
34+
let param_name = generics.params.next_type_param_name(None);
35+
36+
let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() {
37+
(span, format!(", {}: {}", param_name, impl_trait_name))
38+
} else {
39+
(generics.span, format!("<{}: {}>", param_name, impl_trait_name))
40+
};
41+
diag.multipart_suggestion(
42+
format!("alternatively use a blanket \
43+
implementation to implement `{of_trait_name}` for \
44+
all types that also implement `{impl_trait_name}`"),
45+
vec![
46+
(self_ty.span, param_name),
47+
add_generic_sugg,
48+
],
49+
Applicability::MaybeIncorrect,
50+
);
51+
}
52+
}
53+
54+
pub(super) fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
55+
let tcx = self.tcx();
56+
if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
57+
self_ty.kind
58+
{
59+
let needs_bracket = in_path
60+
&& !tcx
61+
.sess
62+
.source_map()
63+
.span_to_prev_source(self_ty.span)
64+
.ok()
65+
.is_some_and(|s| s.trim_end().ends_with('<'));
66+
67+
let is_global = poly_trait_ref.trait_ref.path.is_global();
68+
69+
let mut sugg = Vec::from_iter([(
70+
self_ty.span.shrink_to_lo(),
71+
format!(
72+
"{}dyn {}",
73+
if needs_bracket { "<" } else { "" },
74+
if is_global { "(" } else { "" },
75+
),
76+
)]);
77+
78+
if is_global || needs_bracket {
79+
sugg.push((
80+
self_ty.span.shrink_to_hi(),
81+
format!(
82+
"{}{}",
83+
if is_global { ")" } else { "" },
84+
if needs_bracket { ">" } else { "" },
85+
),
86+
));
87+
}
88+
89+
if self_ty.span.edition().rust_2021() {
90+
let msg = "trait objects must include the `dyn` keyword";
91+
let label = "add `dyn` keyword before this trait";
92+
let mut diag =
93+
rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg);
94+
if self_ty.span.can_be_used_for_suggestions() {
95+
diag.multipart_suggestion_verbose(
96+
label,
97+
sugg,
98+
Applicability::MachineApplicable,
99+
);
100+
}
101+
// check if the impl trait that we are considering is a impl of a local trait
102+
self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
103+
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
104+
} else {
105+
let msg = "trait objects without an explicit `dyn` are deprecated";
106+
tcx.struct_span_lint_hir(
107+
BARE_TRAIT_OBJECTS,
108+
self_ty.hir_id,
109+
self_ty.span,
110+
msg,
111+
|lint| {
112+
lint.multipart_suggestion_verbose(
113+
"use `dyn`",
114+
sugg,
115+
Applicability::MachineApplicable,
116+
);
117+
self.maybe_lint_blanket_trait_impl(&self_ty, lint);
118+
lint
119+
},
120+
);
121+
}
122+
}
123+
}
124+
}

compiler/rustc_hir_analysis/src/astconv/mod.rs

+4-116
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
55
mod errors;
66
pub mod generics;
7+
mod lint;
78

89
use crate::astconv::errors::prohibit_assoc_ty_binding;
910
use crate::astconv::generics::{check_generic_arg_count, create_substs_for_generic_args};
@@ -19,7 +20,7 @@ use rustc_ast::TraitObjectSyntax;
1920
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
2021
use rustc_errors::{
2122
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, FatalError,
22-
MultiSpan, StashKey,
23+
MultiSpan,
2324
};
2425
use rustc_hir as hir;
2526
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@@ -33,14 +34,12 @@ use rustc_middle::ty::subst::{self, GenericArgKind, InternalSubsts, SubstsRef};
3334
use rustc_middle::ty::GenericParamDefKind;
3435
use rustc_middle::ty::{self, Const, IsSuggestable, Ty, TyCtxt, TypeVisitableExt};
3536
use rustc_middle::ty::{DynKind, ToPredicate};
36-
use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, BARE_TRAIT_OBJECTS};
37+
use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
3738
use rustc_span::edit_distance::find_best_match_for_name;
3839
use rustc_span::symbol::{kw, Ident, Symbol};
3940
use rustc_span::{sym, Span, DUMMY_SP};
4041
use rustc_target::spec::abi;
41-
use rustc_trait_selection::traits::error_reporting::{
42-
report_object_safety_error, suggestions::NextTypeParamName,
43-
};
42+
use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
4443
use rustc_trait_selection::traits::wf::object_region_bounds;
4544
use rustc_trait_selection::traits::{
4645
self, astconv_object_safety_violations, NormalizeExt, ObligationCtxt,
@@ -3715,115 +3714,4 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
37153714
}
37163715
Some(r)
37173716
}
3718-
3719-
/// Make sure that we are in the condition to suggest the blanket implementation.
3720-
fn maybe_lint_blanket_trait_impl(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) {
3721-
let tcx = self.tcx();
3722-
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
3723-
if let hir::Node::Item(hir::Item {
3724-
kind:
3725-
hir::ItemKind::Impl(hir::Impl {
3726-
self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, ..
3727-
}),
3728-
..
3729-
}) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id
3730-
{
3731-
if !of_trait_ref.trait_def_id().is_some_and(|def_id| def_id.is_local()) {
3732-
return;
3733-
}
3734-
let of_trait_span = of_trait_ref.path.span;
3735-
// make sure that we are not calling unwrap to abort during the compilation
3736-
let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; };
3737-
let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; };
3738-
// check if the trait has generics, to make a correct suggestion
3739-
let param_name = generics.params.next_type_param_name(None);
3740-
3741-
let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() {
3742-
(span, format!(", {}: {}", param_name, impl_trait_name))
3743-
} else {
3744-
(generics.span, format!("<{}: {}>", param_name, impl_trait_name))
3745-
};
3746-
diag.multipart_suggestion(
3747-
format!("alternatively use a blanket \
3748-
implementation to implement `{of_trait_name}` for \
3749-
all types that also implement `{impl_trait_name}`"),
3750-
vec![
3751-
(self_ty.span, param_name),
3752-
add_generic_sugg,
3753-
],
3754-
Applicability::MaybeIncorrect,
3755-
);
3756-
}
3757-
}
3758-
3759-
fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) {
3760-
let tcx = self.tcx();
3761-
if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
3762-
self_ty.kind
3763-
{
3764-
let needs_bracket = in_path
3765-
&& !tcx
3766-
.sess
3767-
.source_map()
3768-
.span_to_prev_source(self_ty.span)
3769-
.ok()
3770-
.is_some_and(|s| s.trim_end().ends_with('<'));
3771-
3772-
let is_global = poly_trait_ref.trait_ref.path.is_global();
3773-
3774-
let mut sugg = Vec::from_iter([(
3775-
self_ty.span.shrink_to_lo(),
3776-
format!(
3777-
"{}dyn {}",
3778-
if needs_bracket { "<" } else { "" },
3779-
if is_global { "(" } else { "" },
3780-
),
3781-
)]);
3782-
3783-
if is_global || needs_bracket {
3784-
sugg.push((
3785-
self_ty.span.shrink_to_hi(),
3786-
format!(
3787-
"{}{}",
3788-
if is_global { ")" } else { "" },
3789-
if needs_bracket { ">" } else { "" },
3790-
),
3791-
));
3792-
}
3793-
3794-
if self_ty.span.edition().rust_2021() {
3795-
let msg = "trait objects must include the `dyn` keyword";
3796-
let label = "add `dyn` keyword before this trait";
3797-
let mut diag =
3798-
rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg);
3799-
if self_ty.span.can_be_used_for_suggestions() {
3800-
diag.multipart_suggestion_verbose(
3801-
label,
3802-
sugg,
3803-
Applicability::MachineApplicable,
3804-
);
3805-
}
3806-
// check if the impl trait that we are considering is a impl of a local trait
3807-
self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag);
3808-
diag.stash(self_ty.span, StashKey::TraitMissingMethod);
3809-
} else {
3810-
let msg = "trait objects without an explicit `dyn` are deprecated";
3811-
tcx.struct_span_lint_hir(
3812-
BARE_TRAIT_OBJECTS,
3813-
self_ty.hir_id,
3814-
self_ty.span,
3815-
msg,
3816-
|lint| {
3817-
lint.multipart_suggestion_verbose(
3818-
"use `dyn`",
3819-
sugg,
3820-
Applicability::MachineApplicable,
3821-
);
3822-
self.maybe_lint_blanket_trait_impl(&self_ty, lint);
3823-
lint
3824-
},
3825-
);
3826-
}
3827-
}
3828-
}
38293717
}

0 commit comments

Comments
 (0)