1
Fork 0

fix: use LocalDefId instead of HirId in trait res

use LocalDefId instead of HirId in trait resolution to simplify
the obligation clause resolution

Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
This commit is contained in:
Vincenzo Palazzo 2023-01-15 12:58:46 +01:00
parent 6b3cd03fdb
commit 7d2c1103d7
48 changed files with 265 additions and 280 deletions

View file

@ -17,7 +17,6 @@ use crate::traits::{
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic;
use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::CRATE_HIR_ID;
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::util;
use rustc_middle::traits::specialization_graph::OverlapMode;
@ -382,18 +381,14 @@ fn resolve_negative_obligation<'tcx>(
return false;
}
let (body_id, body_def_id) = if let Some(body_def_id) = body_def_id.as_local() {
(tcx.hir().local_def_id_to_hir_id(body_def_id), body_def_id)
} else {
(CRATE_HIR_ID, CRATE_DEF_ID)
};
let body_def_id = body_def_id.as_local().unwrap_or(CRATE_DEF_ID);
let ocx = ObligationCtxt::new(&infcx);
let wf_tys = ocx.assumed_wf_types(param_env, DUMMY_SP, body_def_id);
let outlives_env = OutlivesEnvironment::with_bounds(
param_env,
Some(&infcx),
infcx.implied_bounds_tys(param_env, body_id, wf_tys),
infcx.implied_bounds_tys(param_env, body_def_id, wf_tys),
);
infcx.process_registered_region_obligations(outlives_env.region_bound_pairs(), param_env);

View file

@ -190,8 +190,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
let tcx = self.infcx.tcx;
let assumed_wf_types = tcx.assumed_wf_types(def_id);
let mut implied_bounds = FxIndexSet::default();
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
let cause = ObligationCause::misc(span, hir_id);
let cause = ObligationCause::misc(span, def_id);
for ty in assumed_wf_types {
// FIXME(@lcnr): rustc currently does not check wf for types
// pre-normalization, meaning that implied bounds are sometimes

View file

@ -81,7 +81,7 @@ pub fn recompute_applicable_impls<'tcx>(
);
let predicates =
tcx.predicates_of(obligation.cause.body_id.owner.to_def_id()).instantiate_identity(tcx);
tcx.predicates_of(obligation.cause.body_id.to_def_id()).instantiate_identity(tcx);
for obligation in elaborate_predicates_with_span(tcx, predicates.into_iter()) {
let kind = obligation.predicate.kind();
if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = kind.skip_binder()

View file

@ -839,14 +839,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err.note(s.as_str());
}
if let Some(ref s) = parent_label {
let body = tcx
.hir()
.opt_local_def_id(obligation.cause.body_id)
.unwrap_or_else(|| {
tcx.hir().body_owner_def_id(hir::BodyId {
hir_id: obligation.cause.body_id,
})
});
let body = obligation.cause.body_id;
err.span_label(tcx.def_span(body), s);
}
@ -934,6 +927,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
}
let body_hir_id =
self.tcx.hir().local_def_id_to_hir_id(obligation.cause.body_id);
// Try to report a help message
if is_fn_trait
&& let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
@ -1014,7 +1009,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if !self.report_similar_impl_candidates(
impl_candidates,
trait_ref,
obligation.cause.body_id,
body_hir_id,
&mut err,
true,
) {
@ -1050,7 +1045,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
self.report_similar_impl_candidates(
impl_candidates,
trait_ref,
obligation.cause.body_id,
body_hir_id,
&mut err,
true,
);
@ -2305,10 +2300,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
predicate.to_opt_poly_trait_pred().unwrap(),
);
if impl_candidates.len() < 10 {
let hir =
self.tcx.hir().local_def_id_to_hir_id(obligation.cause.body_id);
self.report_similar_impl_candidates(
impl_candidates,
trait_ref,
body_id.map(|id| id.hir_id).unwrap_or(obligation.cause.body_id),
body_id.map(|id| id.hir_id).unwrap_or(hir),
&mut err,
false,
);

View file

@ -149,10 +149,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
.unwrap_or_else(|| (trait_ref.def_id(), trait_ref.skip_binder().substs));
let trait_ref = trait_ref.skip_binder();
let mut flags = vec![(
sym::ItemContext,
self.describe_enclosure(obligation.cause.body_id).map(|s| s.to_owned()),
)];
let body_hir = self.tcx.hir().local_def_id_to_hir_id(obligation.cause.body_id);
let mut flags =
vec![(sym::ItemContext, self.describe_enclosure(body_hir).map(|s| s.to_owned()))];
match obligation.cause.code() {
ObligationCauseCode::BuiltinDerivedObligation(..)

View file

@ -9,7 +9,6 @@ use crate::infer::InferCtxt;
use crate::traits::{NormalizeExt, ObligationCtxt};
use hir::def::CtorOf;
use hir::{Expr, HirId};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{
@ -22,6 +21,7 @@ use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
use rustc_hir::{Expr, HirId};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime};
@ -34,6 +34,7 @@ use rustc_middle::ty::{
IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder,
TypeSuperFoldable, TypeVisitable, TypeckResults,
};
use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP};
use rustc_target::spec::abi;
@ -179,7 +180,7 @@ pub trait TypeErrCtxtExt<'tcx> {
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
associated_item: Option<(&'static str, Ty<'tcx>)>,
body_id: hir::HirId,
body_id: LocalDefId,
);
fn suggest_dereferences(
@ -522,7 +523,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
mut err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
associated_ty: Option<(&'static str, Ty<'tcx>)>,
body_id: hir::HirId,
body_id: LocalDefId,
) {
let trait_pred = self.resolve_numeric_literals_with_default(trait_pred);
@ -535,8 +536,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// FIXME: Add check for trait bound that is already present, particularly `?Sized` so we
// don't suggest `T: Sized + ?Sized`.
let mut hir_id = body_id;
while let Some(node) = self.tcx.hir().find(hir_id) {
let mut body_id = body_id;
while let Some(node) = self.tcx.hir().find_by_def_id(body_id) {
let hir_id = self.tcx.hir().local_def_id_to_hir_id(body_id);
match node {
hir::Node::Item(hir::Item {
ident,
@ -713,8 +715,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
_ => {}
}
hir_id = self.tcx.hir().get_parent_item(hir_id).into();
body_id = self.tcx.local_parent(body_id);
}
}
@ -905,8 +906,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_pred.self_ty(),
);
let body_hir_id = self.tcx.hir().local_def_id_to_hir_id(obligation.cause.body_id);
let Some((def_id_or_name, output, inputs)) = self.extract_callable_info(
obligation.cause.body_id,
body_hir_id,
obligation.param_env,
self_ty,
) else { return false; };
@ -1004,8 +1006,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
span.remove_mark();
}
let mut expr_finder = FindExprBySpan::new(span);
let Some(hir::Node::Expr(body)) = self.tcx.hir().find(obligation.cause.body_id) else { return; };
expr_finder.visit_expr(&body);
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return; };
let body = self.tcx.hir().body(body_id);
expr_finder.visit_expr(body.value);
let Some(expr) = expr_finder.result else { return; };
let Some(typeck) = &self.typeck_results else { return; };
let Some(ty) = typeck.expr_ty_adjusted_opt(expr) else { return; };
@ -1060,8 +1063,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
) -> bool {
let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
let ty = self.tcx.erase_late_bound_regions(self_ty);
let owner = self.tcx.hir().get_parent_item(obligation.cause.body_id);
let Some(generics) = self.tcx.hir().get_generics(owner.def_id) else { return false };
let Some(generics) = self.tcx.hir().get_generics(obligation.cause.body_id) else { return false };
let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false };
let ty::Param(param) = inner_ty.kind() else { return false };
let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } = obligation.cause.code() else { return false };
@ -1104,6 +1106,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
/// Extracts information about a callable type for diagnostics. This is a
/// heuristic -- it doesn't necessarily mean that a type is always callable,
/// because the callable type must also be well-formed to be called.
// FIXME(vincenzopalazzo): move the HirId to a LocalDefId
fn extract_callable_info(
&self,
hir_id: HirId,
@ -1429,10 +1432,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
span.remove_mark();
}
let mut expr_finder = super::FindExprBySpan::new(span);
let Some(hir::Node::Expr(body)) = self.tcx.hir().find(obligation.cause.body_id) else {
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else {
return false;
};
expr_finder.visit_expr(&body);
let body = self.tcx.hir().body(body_id);
expr_finder.visit_expr(body.value);
let mut maybe_suggest = |suggested_ty, count, suggestions| {
// Remapping bound vars here
let trait_pred_and_suggested_ty =
@ -1670,8 +1674,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool {
let hir = self.tcx.hir();
let parent_node = hir.parent_id(obligation.cause.body_id);
let node = hir.find(parent_node);
let node = hir.find_by_def_id(obligation.cause.body_id);
if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })) = node
&& let hir::ExprKind::Block(blk, _) = &hir.body(*body_id).value.kind
&& sig.decl.output.span().overlaps(span)
@ -1707,8 +1710,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
fn return_type_span(&self, obligation: &PredicateObligation<'tcx>) -> Option<Span> {
let hir = self.tcx.hir();
let parent_node = hir.parent_id(obligation.cause.body_id);
let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) = hir.find(parent_node) else {
let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, ..), .. })) = hir.find_by_def_id(obligation.cause.body_id) else {
return None;
};
@ -1732,8 +1734,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
let hir = self.tcx.hir();
let fn_hir_id = hir.parent_id(obligation.cause.body_id);
let node = hir.find(fn_hir_id);
let fn_hir_id = hir.local_def_id_to_hir_id(obligation.cause.body_id);
let node = hir.find_by_def_id(obligation.cause.body_id);
let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(sig, _, body_id),
..
@ -1806,7 +1808,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
match liberated_sig.output().kind() {
ty::Dynamic(predicates, _, ty::Dyn) => {
let cause = ObligationCause::misc(ret_ty.span, fn_hir_id);
let cause = ObligationCause::misc(ret_ty.span, obligation.cause.body_id);
let param_env = ty::ParamEnv::empty();
if !only_never_return {
@ -1944,8 +1946,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
let hir = self.tcx.hir();
let parent_node = hir.parent_id(obligation.cause.body_id);
let node = hir.find(parent_node);
let node = hir.find_by_def_id(obligation.cause.body_id);
if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) =
node
{
@ -3283,12 +3284,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
trait_pred: ty::PolyTraitPredicate<'tcx>,
span: Span,
) {
let body_hir_id = obligation.cause.body_id;
let item_id = self.tcx.hir().parent_id(body_hir_id);
if let Some(body_id) =
self.tcx.hir().maybe_body_owned_by(self.tcx.hir().local_def_id(item_id))
{
if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) {
let body = self.tcx.hir().body(body_id);
if let Some(hir::GeneratorKind::Async(_)) = body.generator_kind {
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
@ -3727,9 +3723,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
term: ty_var.into(),
},
)));
let body_def_id = self.tcx.hir().enclosing_body_owner(body_id);
// Add `<ExprTy as Iterator>::Item = _` obligation.
ocx.register_obligation(Obligation::misc(
self.tcx, span, body_id, param_env, projection,
self.tcx,
span,
body_def_id,
param_env,
projection,
));
if ocx.select_where_possible().is_empty() {
// `ty_var` now holds the type that `Item` is for `ExprTy`.

View file

@ -26,12 +26,11 @@ use crate::infer::{InferCtxt, TyCtxtInferExt};
use crate::traits::error_reporting::TypeErrCtxtExt as _;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
use rustc_errors::ErrorGuaranteed;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_middle::ty::fold::TypeFoldable;
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{self, DefIdTree, ToPredicate, Ty, TyCtxt, TypeSuperVisitable};
use rustc_middle::ty::{InternalSubsts, SubstsRef};
use rustc_span::def_id::{DefId, CRATE_DEF_ID};
use rustc_span::Span;
use std::fmt::Debug;
@ -151,7 +150,7 @@ fn pred_known_to_hold_modulo_regions<'tcx>(
// We can use a dummy node-id here because we won't pay any mind
// to region obligations that arise (there shouldn't really be any
// anyhow).
cause: ObligationCause::misc(span, hir::CRATE_HIR_ID),
cause: ObligationCause::misc(span, CRATE_DEF_ID),
recursion_depth: 0,
predicate: pred.to_predicate(infcx.tcx),
};
@ -166,14 +165,12 @@ fn pred_known_to_hold_modulo_regions<'tcx>(
// that guess. While imperfect, I believe this is sound.
// FIXME(@lcnr): this function doesn't seem right.
//
// The handling of regions in this area of the code is terrible,
// see issue #29149. We should be able to improve on this with
// NLL.
let errors = fully_solve_obligation(infcx, obligation);
// Note: we only assume something is `Copy` if we can
// *definitively* show that it implements `Copy`. Otherwise,
// assume it is move; linear is always ok.
match &errors[..] {
[] => true,
errors => {

View file

@ -3,9 +3,8 @@ use crate::traits::query::type_op::{self, TypeOp, TypeOpOutput};
use crate::traits::query::NoSolution;
use crate::traits::ObligationCause;
use rustc_data_structures::fx::FxIndexSet;
use rustc_hir as hir;
use rustc_hir::HirId;
use rustc_middle::ty::{self, ParamEnv, Ty};
use rustc_span::def_id::LocalDefId;
pub use rustc_middle::traits::query::OutlivesBound;
@ -14,14 +13,14 @@ pub trait InferCtxtExt<'a, 'tcx> {
fn implied_outlives_bounds(
&self,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
body_id: LocalDefId,
ty: Ty<'tcx>,
) -> Vec<OutlivesBound<'tcx>>;
fn implied_bounds_tys(
&'a self,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
body_id: LocalDefId,
tys: FxIndexSet<Ty<'tcx>>,
) -> Bounds<'a, 'tcx>;
}
@ -50,10 +49,10 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
fn implied_outlives_bounds(
&self,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
body_id: LocalDefId,
ty: Ty<'tcx>,
) -> Vec<OutlivesBound<'tcx>> {
let span = self.tcx.hir().span(body_id);
let span = self.tcx.def_span(body_id);
let result = param_env
.and(type_op::implied_outlives_bounds::ImpliedOutlivesBounds { ty })
.fully_perform(self);
@ -102,7 +101,7 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
fn implied_bounds_tys(
&'a self,
param_env: ParamEnv<'tcx>,
body_id: HirId,
body_id: LocalDefId,
tys: FxIndexSet<Ty<'tcx>>,
) -> Bounds<'a, 'tcx> {
tys.into_iter()

View file

@ -1,10 +1,10 @@
use crate::infer::InferCtxt;
use crate::traits;
use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
use rustc_span::def_id::{DefId, LocalDefId};
use rustc_span::Span;
use std::iter;
@ -17,7 +17,7 @@ use std::iter;
pub fn obligations<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
body_id: LocalDefId,
recursion_depth: usize,
arg: GenericArg<'tcx>,
span: Span,
@ -82,7 +82,7 @@ pub fn obligations<'tcx>(
pub fn trait_obligations<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
body_id: LocalDefId,
trait_pred: &ty::TraitPredicate<'tcx>,
span: Span,
item: &'tcx hir::Item<'tcx>,
@ -105,7 +105,7 @@ pub fn trait_obligations<'tcx>(
pub fn predicate_obligations<'tcx>(
infcx: &InferCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
body_id: LocalDefId,
predicate: ty::Predicate<'tcx>,
span: Span,
) -> Vec<traits::PredicateObligation<'tcx>> {
@ -167,7 +167,7 @@ pub fn predicate_obligations<'tcx>(
struct WfPredicates<'tcx> {
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
body_id: hir::HirId,
body_id: LocalDefId,
span: Span,
out: Vec<traits::PredicateObligation<'tcx>>,
recursion_depth: usize,