Address comments

This commit is contained in:
Michael Goulet 2022-12-27 17:53:29 +00:00
parent 7690fe3bc6
commit 2baee88bdb
4 changed files with 52 additions and 117 deletions

View file

@ -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);
} }

View file

@ -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,37 +390,37 @@ 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 {
{
Some(Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }), kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
.. ..
})) => Some((impl_item.ident, self_ty)), }) = tcx.hir().owner(impl_did)
_ => None, {
Some((impl_item.ident, self_ty))
} else {
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_did.to_def_id(); let trait_did = trait_id.to_def_id();
match tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| { tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
match tcx.hir().get_if_local(impl_did.to_def_id()) { if let Node::Item(Item {
Some(Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }), kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
.. ..
})) if trait_objects.iter().all(|did| { }) = tcx.hir().find_by_def_id(impl_did)?
&& 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
@ -431,19 +431,13 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
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(self_ty) Some((trait_item.ident, *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;
}; };

View file

@ -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 {