Address comments
This commit is contained in:
parent
7690fe3bc6
commit
2baee88bdb
4 changed files with 52 additions and 117 deletions
|
@ -535,12 +535,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
// x += 1;
|
// x += 1;
|
||||||
// ```
|
// ```
|
||||||
!i.contains(span)
|
!i.contains(span)
|
||||||
// We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
|
// We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
|
||||||
&& !visitor
|
&& !visitor
|
||||||
.errors
|
.errors
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(sp, _)| *sp)
|
.map(|(sp, _)| *sp)
|
||||||
.any(|sp| span < sp && !sp.contains(span))
|
.any(|sp| span < sp && !sp.contains(span))
|
||||||
}) {
|
}) {
|
||||||
show_assign_sugg = true;
|
show_assign_sugg = true;
|
||||||
"isn't initialized"
|
"isn't initialized"
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxIndexSet;
|
use rustc_data_structures::fx::FxIndexSet;
|
||||||
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
|
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
|
||||||
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
use rustc_hir::{self as hir, Item, ItemKind, Node};
|
|
||||||
use rustc_infer::infer::{
|
use rustc_infer::infer::{
|
||||||
error_reporting::nice_region_error::{
|
error_reporting::nice_region_error::{
|
||||||
self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params,
|
self, find_anon_type, find_param_with_region, suggest_adding_lifetime_params,
|
||||||
|
@ -291,65 +291,6 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
outlives_suggestion.add_suggestion(self);
|
outlives_suggestion.add_suggestion(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_impl_ident_and_self_ty_from_trait(
|
|
||||||
&self,
|
|
||||||
def_id: DefId,
|
|
||||||
trait_objects: &FxIndexSet<DefId>,
|
|
||||||
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
|
|
||||||
let tcx = self.infcx.tcx;
|
|
||||||
match tcx.hir().get_if_local(def_id) {
|
|
||||||
Some(Node::ImplItem(impl_item)) => {
|
|
||||||
match tcx.hir().find_by_def_id(tcx.hir().get_parent_item(impl_item.hir_id()).def_id)
|
|
||||||
{
|
|
||||||
Some(Node::Item(Item {
|
|
||||||
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
|
|
||||||
..
|
|
||||||
})) => Some((impl_item.ident, self_ty)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(Node::TraitItem(trait_item)) => {
|
|
||||||
let trait_did = tcx.hir().get_parent_item(trait_item.hir_id());
|
|
||||||
match tcx.hir().find_by_def_id(trait_did.def_id) {
|
|
||||||
Some(Node::Item(Item { kind: ItemKind::Trait(..), .. })) => {
|
|
||||||
// The method being called is defined in the `trait`, but the `'static`
|
|
||||||
// obligation comes from the `impl`. Find that `impl` so that we can point
|
|
||||||
// at it in the suggestion.
|
|
||||||
let trait_did = trait_did.to_def_id();
|
|
||||||
match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
|
|
||||||
match tcx.hir().get_if_local(impl_did.to_def_id()) {
|
|
||||||
Some(Node::Item(Item {
|
|
||||||
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
|
|
||||||
..
|
|
||||||
})) if trait_objects.iter().all(|did| {
|
|
||||||
// FIXME: we should check `self_ty` against the receiver
|
|
||||||
// type in the `UnifyReceiver` context, but for now, use
|
|
||||||
// this imperfect proxy. This will fail if there are
|
|
||||||
// multiple `impl`s for the same trait like
|
|
||||||
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
|
|
||||||
// In that case, only the first one will get suggestions.
|
|
||||||
let mut traits = vec![];
|
|
||||||
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
|
|
||||||
hir_v.visit_ty(self_ty);
|
|
||||||
!traits.is_empty()
|
|
||||||
}) =>
|
|
||||||
{
|
|
||||||
Some(self_ty)
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
Some(self_ty) => Some((trait_item.ident, self_ty)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Report an error because the universal region `fr` was required to outlive
|
/// Report an error because the universal region `fr` was required to outlive
|
||||||
/// `outlived_fr` but it is not known to do so. For example:
|
/// `outlived_fr` but it is not known to do so. For example:
|
||||||
///
|
///
|
||||||
|
@ -844,7 +785,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||||
visitor.visit_ty(param.param_ty);
|
visitor.visit_ty(param.param_ty);
|
||||||
|
|
||||||
let Some((ident, self_ty)) =
|
let Some((ident, self_ty)) =
|
||||||
self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &visitor.0) else {return};
|
NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &visitor.0) else { return; };
|
||||||
|
|
||||||
self.suggest_constrain_dyn_trait_in_impl(diag, &visitor.0, ident, self_ty);
|
self.suggest_constrain_dyn_trait_in_impl(diag, &visitor.0, ident, self_ty);
|
||||||
}
|
}
|
||||||
|
|
|
@ -239,7 +239,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
let mut v = TraitObjectVisitor(FxIndexSet::default());
|
let mut v = TraitObjectVisitor(FxIndexSet::default());
|
||||||
v.visit_ty(param.param_ty);
|
v.visit_ty(param.param_ty);
|
||||||
if let Some((ident, self_ty)) =
|
if let Some((ident, self_ty)) =
|
||||||
self.get_impl_ident_and_self_ty_from_trait(item_def_id, &v.0)
|
NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, item_def_id, &v.0)
|
||||||
&& self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty)
|
&& self.suggest_constrain_dyn_trait_in_impl(&mut err, &v.0, ident, self_ty)
|
||||||
{
|
{
|
||||||
override_error_code = Some(ident.name);
|
override_error_code = Some(ident.name);
|
||||||
|
@ -390,60 +390,54 @@ pub fn suggest_new_region_bound(
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
fn get_impl_ident_and_self_ty_from_trait(
|
pub fn get_impl_ident_and_self_ty_from_trait(
|
||||||
&self,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
trait_objects: &FxIndexSet<DefId>,
|
trait_objects: &FxIndexSet<DefId>,
|
||||||
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
|
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
|
||||||
let tcx = self.tcx();
|
match tcx.hir().get_if_local(def_id)? {
|
||||||
match tcx.hir().get_if_local(def_id) {
|
Node::ImplItem(impl_item) => {
|
||||||
Some(Node::ImplItem(impl_item)) => {
|
let impl_did = tcx.hir().get_parent_item(impl_item.hir_id());
|
||||||
match tcx.hir().find_by_def_id(tcx.hir().get_parent_item(impl_item.hir_id()).def_id)
|
if let hir::OwnerNode::Item(Item {
|
||||||
|
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
|
||||||
|
..
|
||||||
|
}) = tcx.hir().owner(impl_did)
|
||||||
{
|
{
|
||||||
Some(Node::Item(Item {
|
Some((impl_item.ident, self_ty))
|
||||||
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
|
} else {
|
||||||
..
|
None
|
||||||
})) => Some((impl_item.ident, self_ty)),
|
|
||||||
_ => None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(Node::TraitItem(trait_item)) => {
|
Node::TraitItem(trait_item) => {
|
||||||
let trait_did = tcx.hir().get_parent_item(trait_item.hir_id());
|
let trait_id = tcx.hir().get_parent_item(trait_item.hir_id());
|
||||||
match tcx.hir().find_by_def_id(trait_did.def_id) {
|
debug_assert_eq!(tcx.def_kind(trait_id.def_id), hir::def::DefKind::Trait);
|
||||||
Some(Node::Item(Item { kind: ItemKind::Trait(..), .. })) => {
|
// The method being called is defined in the `trait`, but the `'static`
|
||||||
// The method being called is defined in the `trait`, but the `'static`
|
// obligation comes from the `impl`. Find that `impl` so that we can point
|
||||||
// obligation comes from the `impl`. Find that `impl` so that we can point
|
// at it in the suggestion.
|
||||||
// at it in the suggestion.
|
let trait_did = trait_id.to_def_id();
|
||||||
let trait_did = trait_did.to_def_id();
|
tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
|
||||||
match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
|
if let Node::Item(Item {
|
||||||
match tcx.hir().get_if_local(impl_did.to_def_id()) {
|
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
|
||||||
Some(Node::Item(Item {
|
..
|
||||||
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
|
}) = tcx.hir().find_by_def_id(impl_did)?
|
||||||
..
|
&& trait_objects.iter().all(|did| {
|
||||||
})) if trait_objects.iter().all(|did| {
|
// FIXME: we should check `self_ty` against the receiver
|
||||||
// FIXME: we should check `self_ty` against the receiver
|
// type in the `UnifyReceiver` context, but for now, use
|
||||||
// type in the `UnifyReceiver` context, but for now, use
|
// this imperfect proxy. This will fail if there are
|
||||||
// this imperfect proxy. This will fail if there are
|
// multiple `impl`s for the same trait like
|
||||||
// multiple `impl`s for the same trait like
|
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
|
||||||
// `impl Foo for Box<dyn Bar>` and `impl Foo for dyn Bar`.
|
// In that case, only the first one will get suggestions.
|
||||||
// In that case, only the first one will get suggestions.
|
let mut traits = vec![];
|
||||||
let mut traits = vec![];
|
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
|
||||||
let mut hir_v = HirTraitObjectVisitor(&mut traits, *did);
|
hir_v.visit_ty(self_ty);
|
||||||
hir_v.visit_ty(self_ty);
|
!traits.is_empty()
|
||||||
!traits.is_empty()
|
})
|
||||||
}) =>
|
{
|
||||||
{
|
Some((trait_item.ident, *self_ty))
|
||||||
Some(self_ty)
|
} else {
|
||||||
}
|
None
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
Some(self_ty) => Some((trait_item.ident, self_ty)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => None,
|
})
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -474,7 +468,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
||||||
|
|
||||||
// Get the `Ident` of the method being called and the corresponding `impl` (to point at
|
// Get the `Ident` of the method being called and the corresponding `impl` (to point at
|
||||||
// `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
|
// `Bar` in `impl Foo for dyn Bar {}` and the definition of the method being called).
|
||||||
let Some((ident, self_ty)) = self.get_impl_ident_and_self_ty_from_trait(instance.def_id(), &v.0) else {
|
let Some((ident, self_ty)) = NiceRegionError::get_impl_ident_and_self_ty_from_trait(tcx, instance.def_id(), &v.0) else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -276,10 +276,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
|
||||||
{
|
{
|
||||||
let def_id = trait_ref.def_id;
|
let def_id = trait_ref.def_id;
|
||||||
is_def_must_use(cx, def_id, span)
|
is_def_must_use(cx, def_id, span)
|
||||||
|
.map(|inner| MustUsePath::TraitObject(Box::new(inner)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
.map(|inner| MustUsePath::TraitObject(Box::new(inner)))
|
|
||||||
}),
|
}),
|
||||||
ty::Tuple(tys) => {
|
ty::Tuple(tys) => {
|
||||||
let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind {
|
let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue