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

@ -535,12 +535,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// x += 1;
// ```
!i.contains(span)
// We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
&& !visitor
.errors
.iter()
.map(|(sp, _)| *sp)
.any(|sp| span < sp && !sp.contains(span))
// We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs`
&& !visitor
.errors
.iter()
.map(|(sp, _)| *sp)
.any(|sp| span < sp && !sp.contains(span))
}) {
show_assign_sugg = true;
"isn't initialized"

View file

@ -4,9 +4,9 @@
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::{self as hir, Item, ItemKind, Node};
use rustc_infer::infer::{
error_reporting::nice_region_error::{
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);
}
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
/// `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);
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);
}

View file

@ -239,7 +239,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let mut v = TraitObjectVisitor(FxIndexSet::default());
v.visit_ty(param.param_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)
{
override_error_code = Some(ident.name);
@ -390,60 +390,54 @@ pub fn suggest_new_region_bound(
}
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
fn get_impl_ident_and_self_ty_from_trait(
&self,
pub fn get_impl_ident_and_self_ty_from_trait(
tcx: TyCtxt<'tcx>,
def_id: DefId,
trait_objects: &FxIndexSet<DefId>,
) -> Option<(Ident, &'tcx hir::Ty<'tcx>)> {
let tcx = self.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)
match tcx.hir().get_if_local(def_id)? {
Node::ImplItem(impl_item) => {
let impl_did = tcx.hir().get_parent_item(impl_item.hir_id());
if let hir::OwnerNode::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
}) = tcx.hir().owner(impl_did)
{
Some(Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
})) => Some((impl_item.ident, self_ty)),
_ => None,
Some((impl_item.ident, self_ty))
} else {
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,
}
Node::TraitItem(trait_item) => {
let trait_id = tcx.hir().get_parent_item(trait_item.hir_id());
debug_assert_eq!(tcx.def_kind(trait_id.def_id), hir::def::DefKind::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_id.to_def_id();
tcx.hir().trait_impls(trait_did).iter().find_map(|&impl_did| {
if let Node::Item(Item {
kind: ItemKind::Impl(hir::Impl { self_ty, .. }),
..
}) = tcx.hir().find_by_def_id(impl_did)?
&& 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((trait_item.ident, *self_ty))
} else {
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
// `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;
};

View file

@ -276,10 +276,10 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
{
let def_id = trait_ref.def_id;
is_def_must_use(cx, def_id, span)
.map(|inner| MustUsePath::TraitObject(Box::new(inner)))
} else {
None
}
.map(|inner| MustUsePath::TraitObject(Box::new(inner)))
}),
ty::Tuple(tys) => {
let elem_exprs = if let hir::ExprKind::Tup(elem_exprs) = expr.kind {