Refactor rustc lint API
This commit is contained in:
@@ -82,14 +82,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
prelude_or_array_lint,
|
||||
self_expr.hir_id,
|
||||
self_expr.span,
|
||||
format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name),
|
||||
|lint| {
|
||||
let sp = self_expr.span;
|
||||
|
||||
let mut lint = lint.build(&format!(
|
||||
"trait method `{}` will become ambiguous in Rust 2021",
|
||||
segment.ident.name
|
||||
));
|
||||
|
||||
let derefs = "*".repeat(pick.autoderefs);
|
||||
|
||||
let autoref = match pick.autoref_or_ptr_adjustment {
|
||||
@@ -133,7 +129,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
lint.emit();
|
||||
lint
|
||||
},
|
||||
);
|
||||
} else {
|
||||
@@ -143,6 +139,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
prelude_or_array_lint,
|
||||
call_expr.hir_id,
|
||||
call_expr.span,
|
||||
format!("trait method `{}` will become ambiguous in Rust 2021", segment.ident.name),
|
||||
|lint| {
|
||||
let sp = call_expr.span;
|
||||
let trait_name = self.trait_path_or_bare_name(
|
||||
@@ -151,11 +148,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
pick.item.container_id(self.tcx),
|
||||
);
|
||||
|
||||
let mut lint = lint.build(&format!(
|
||||
"trait method `{}` will become ambiguous in Rust 2021",
|
||||
segment.ident.name
|
||||
));
|
||||
|
||||
let (self_adjusted, precise) = self.adjust_expr(pick, self_expr, sp);
|
||||
if precise {
|
||||
let args = args
|
||||
@@ -202,7 +194,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
lint.emit();
|
||||
lint
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -257,15 +249,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return;
|
||||
}
|
||||
|
||||
self.tcx.struct_span_lint_hir(RUST_2021_PRELUDE_COLLISIONS, expr_id, span, |lint| {
|
||||
// "type" refers to either a type or, more likely, a trait from which
|
||||
// the associated function or method is from.
|
||||
let container_id = pick.item.container_id(self.tcx);
|
||||
let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
|
||||
let trait_generics = self.tcx.generics_of(container_id);
|
||||
self.tcx.struct_span_lint_hir(
|
||||
RUST_2021_PRELUDE_COLLISIONS,
|
||||
expr_id,
|
||||
span,
|
||||
format!(
|
||||
"trait-associated function `{}` will become ambiguous in Rust 2021",
|
||||
method_name.name
|
||||
),
|
||||
|lint| {
|
||||
// "type" refers to either a type or, more likely, a trait from which
|
||||
// the associated function or method is from.
|
||||
let container_id = pick.item.container_id(self.tcx);
|
||||
let trait_path = self.trait_path_or_bare_name(span, expr_id, container_id);
|
||||
let trait_generics = self.tcx.generics_of(container_id);
|
||||
|
||||
let trait_name =
|
||||
if trait_generics.params.len() <= trait_generics.has_self as usize {
|
||||
let trait_name = if trait_generics.params.len() <= trait_generics.has_self as usize
|
||||
{
|
||||
trait_path
|
||||
} else {
|
||||
let counts = trait_generics.own_counts();
|
||||
@@ -282,44 +282,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
)
|
||||
};
|
||||
|
||||
let mut lint = lint.build(&format!(
|
||||
"trait-associated function `{}` will become ambiguous in Rust 2021",
|
||||
method_name.name
|
||||
));
|
||||
let mut self_ty_name = self_ty_span
|
||||
.find_ancestor_inside(span)
|
||||
.and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
|
||||
.unwrap_or_else(|| self_ty.to_string());
|
||||
|
||||
let mut self_ty_name = self_ty_span
|
||||
.find_ancestor_inside(span)
|
||||
.and_then(|span| self.sess().source_map().span_to_snippet(span).ok())
|
||||
.unwrap_or_else(|| self_ty.to_string());
|
||||
|
||||
// Get the number of generics the self type has (if an Adt) unless we can determine that
|
||||
// the user has written the self type with generics already which we (naively) do by looking
|
||||
// for a "<" in `self_ty_name`.
|
||||
if !self_ty_name.contains('<') {
|
||||
if let Adt(def, _) = self_ty.kind() {
|
||||
let generics = self.tcx.generics_of(def.did());
|
||||
if !generics.params.is_empty() {
|
||||
let counts = generics.own_counts();
|
||||
self_ty_name += &format!(
|
||||
"<{}>",
|
||||
std::iter::repeat("'_")
|
||||
.take(counts.lifetimes)
|
||||
.chain(std::iter::repeat("_").take(counts.types + counts.consts))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
// Get the number of generics the self type has (if an Adt) unless we can determine that
|
||||
// the user has written the self type with generics already which we (naively) do by looking
|
||||
// for a "<" in `self_ty_name`.
|
||||
if !self_ty_name.contains('<') {
|
||||
if let Adt(def, _) = self_ty.kind() {
|
||||
let generics = self.tcx.generics_of(def.did());
|
||||
if !generics.params.is_empty() {
|
||||
let counts = generics.own_counts();
|
||||
self_ty_name += &format!(
|
||||
"<{}>",
|
||||
std::iter::repeat("'_")
|
||||
.take(counts.lifetimes)
|
||||
.chain(
|
||||
std::iter::repeat("_").take(counts.types + counts.consts)
|
||||
)
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"disambiguate the associated function",
|
||||
format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
lint.span_suggestion(
|
||||
span,
|
||||
"disambiguate the associated function",
|
||||
format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
|
||||
lint.emit();
|
||||
});
|
||||
lint
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
fn trait_path_or_bare_name(
|
||||
|
||||
@@ -409,9 +409,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
lint::builtin::TYVAR_BEHIND_RAW_POINTER,
|
||||
scope_expr_id,
|
||||
span,
|
||||
|lint| {
|
||||
lint.build("type annotations needed").emit();
|
||||
},
|
||||
"type annotations needed",
|
||||
|lint| lint,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@@ -1358,24 +1357,24 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
stable_pick: &Pick<'_>,
|
||||
unstable_candidates: &[(Candidate<'tcx>, Symbol)],
|
||||
) {
|
||||
let def_kind = stable_pick.item.kind.as_def_kind();
|
||||
self.tcx.struct_span_lint_hir(
|
||||
lint::builtin::UNSTABLE_NAME_COLLISIONS,
|
||||
self.scope_expr_id,
|
||||
self.span,
|
||||
format!(
|
||||
"{} {} with this name may be added to the standard library in the future",
|
||||
def_kind.article(),
|
||||
def_kind.descr(stable_pick.item.def_id),
|
||||
),
|
||||
|lint| {
|
||||
let def_kind = stable_pick.item.kind.as_def_kind();
|
||||
let mut diag = lint.build(&format!(
|
||||
"{} {} with this name may be added to the standard library in the future",
|
||||
def_kind.article(),
|
||||
def_kind.descr(stable_pick.item.def_id),
|
||||
));
|
||||
match (stable_pick.item.kind, stable_pick.item.container) {
|
||||
(ty::AssocKind::Fn, _) => {
|
||||
// FIXME: This should be a `span_suggestion` instead of `help`
|
||||
// However `self.span` only
|
||||
// highlights the method name, so we can't use it. Also consider reusing
|
||||
// the code from `report_method_error()`.
|
||||
diag.help(&format!(
|
||||
lint.help(&format!(
|
||||
"call with fully qualified syntax `{}(...)` to keep using the current \
|
||||
method",
|
||||
self.tcx.def_path_str(stable_pick.item.def_id),
|
||||
@@ -1383,7 +1382,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
(ty::AssocKind::Const, ty::AssocItemContainer::TraitContainer) => {
|
||||
let def_id = stable_pick.item.container_id(self.tcx);
|
||||
diag.span_suggestion(
|
||||
lint.span_suggestion(
|
||||
self.span,
|
||||
"use the fully qualified path to the associated const",
|
||||
format!(
|
||||
@@ -1399,7 +1398,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
if self.tcx.sess.is_nightly_build() {
|
||||
for (candidate, feature) in unstable_candidates {
|
||||
diag.help(&format!(
|
||||
lint.help(&format!(
|
||||
"add `#![feature({})]` to the crate attributes to enable `{}`",
|
||||
feature,
|
||||
self.tcx.def_path_str(candidate.item.def_id),
|
||||
@@ -1407,7 +1406,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
diag.emit();
|
||||
lint
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user