Rework point-at-arg

This commit is contained in:
Michael Goulet 2022-08-16 06:27:22 +00:00
parent fb80d2bfe4
commit c005e760f5
155 changed files with 1276 additions and 789 deletions

View file

@ -1564,6 +1564,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
obligation.cause.code().peel_derives(),
ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::BindingObligation(_, _)
| ObligationCauseCode::ExprItemObligation(..)
| ObligationCauseCode::ExprBindingObligation(..)
| ObligationCauseCode::ObjectCastObligation(..)
| ObligationCauseCode::OpaqueType
);
@ -2091,13 +2093,11 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
}
}
if let ObligationCauseCode::ItemObligation(def_id) = *obligation.cause.code() {
if let ObligationCauseCode::ItemObligation(def_id) | ObligationCauseCode::ExprItemObligation(def_id, ..) = *obligation.cause.code() {
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
} else if let (
Ok(ref snippet),
&ObligationCauseCode::BindingObligation(def_id, _),
) =
(self.tcx.sess.source_map().span_to_snippet(span), obligation.cause.code())
} else if let Ok(snippet) = &self.tcx.sess.source_map().span_to_snippet(span)
&& let ObligationCauseCode::BindingObligation(def_id, _) | ObligationCauseCode::ExprBindingObligation(def_id, ..)
= *obligation.cause.code()
{
let generics = self.tcx.generics_of(def_id);
if generics.params.iter().any(|p| p.name != kw::SelfUpper)
@ -2520,15 +2520,10 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
err: &mut Diagnostic,
obligation: &PredicateObligation<'tcx>,
) {
let (
ty::PredicateKind::Trait(pred),
&ObligationCauseCode::BindingObligation(item_def_id, span),
) = (
obligation.predicate.kind().skip_binder(),
obligation.cause.code().peel_derives(),
) else {
return;
};
let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; };
let (ObligationCauseCode::BindingObligation(item_def_id, span)
| ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..))
= *obligation.cause.code().peel_derives() else { return; };
debug!(?pred, ?item_def_id, ?span);
let (Some(node), true) = (

View file

@ -143,7 +143,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
}
if let ObligationCauseCode::ItemObligation(item)
| ObligationCauseCode::BindingObligation(item, _) = *obligation.cause.code()
| ObligationCauseCode::BindingObligation(item, _)
| ObligationCauseCode::ExprItemObligation(item, ..)
| ObligationCauseCode::ExprBindingObligation(item, ..) = *obligation.cause.code()
{
// FIXME: maybe also have some way of handling methods
// from other traits? That would require name resolution,

View file

@ -1022,7 +1022,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
if let ObligationCauseCode::ImplDerivedObligation(cause) = &*code {
try_borrowing(cause.derived.parent_trait_pred, &[])
} else if let ObligationCauseCode::BindingObligation(_, _)
| ObligationCauseCode::ItemObligation(..) = code
| ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::ExprItemObligation(..)
| ObligationCauseCode::ExprBindingObligation(..) = code
{
try_borrowing(poly_trait_pred, &never_suggest_borrow)
} else {
@ -2244,11 +2246,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
region, object_ty,
));
}
ObligationCauseCode::ItemObligation(_item_def_id) => {
ObligationCauseCode::ItemObligation(_)
| ObligationCauseCode::ExprItemObligation(..) => {
// We hold the `DefId` of the item introducing the obligation, but displaying it
// doesn't add user usable information. It always point at an associated item.
}
ObligationCauseCode::BindingObligation(item_def_id, span) => {
ObligationCauseCode::BindingObligation(item_def_id, span)
| ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..) => {
let item_name = tcx.def_path_str(item_def_id);
let mut multispan = MultiSpan::from(span);
if let Some(ident) = tcx.opt_item_ident(item_def_id) {

View file

@ -117,11 +117,21 @@ pub enum TraitQueryMode {
/// Creates predicate obligations from the generic bounds.
pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>,
cause: impl Fn(usize, Span) -> ObligationCause<'tcx>,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: ty::InstantiatedPredicates<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
util::predicates_for_generics(cause, 0, param_env, generic_bounds)
let generic_bounds = generic_bounds;
debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);
std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map(
move |(idx, (predicate, span))| Obligation {
cause: cause(idx, span),
recursion_depth: 0,
param_env: param_env,
predicate,
},
)
}
/// Determines whether the type `ty` is known to meet `bound` and

View file

@ -11,8 +11,6 @@ use rustc_middle::ty::{self, ImplSubject, ToPredicate, Ty, TyCtxt, TypeVisitable
use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
pub use rustc_infer::traits::{self, util::*};
use std::iter;
///////////////////////////////////////////////////////////////////////////
// `TraitAliasExpander` iterator
///////////////////////////////////////////////////////////////////////////
@ -210,7 +208,7 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
let Normalized { value: predicates, obligations: normalization_obligations2 } =
super::normalize(selcx, param_env, ObligationCause::dummy(), predicates);
let impl_obligations =
predicates_for_generics(ObligationCause::dummy(), 0, param_env, predicates);
super::predicates_for_generics(|_, _| ObligationCause::dummy(), param_env, predicates);
let impl_obligations = impl_obligations
.chain(normalization_obligations1.into_iter())
@ -219,27 +217,6 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
(subject, impl_obligations)
}
pub fn predicates_for_generics<'tcx>(
cause: ObligationCause<'tcx>,
recursion_depth: usize,
param_env: ty::ParamEnv<'tcx>,
generic_bounds: ty::InstantiatedPredicates<'tcx>,
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
debug!("predicates_for_generics(generic_bounds={:?})", generic_bounds);
iter::zip(generic_bounds.predicates, generic_bounds.spans).map(move |(predicate, span)| {
let cause = match *cause.code() {
traits::ItemObligation(def_id) if !span.is_dummy() => traits::ObligationCause::new(
cause.span,
cause.body_id,
traits::BindingObligation(def_id, span),
),
_ => cause.clone(),
};
Obligation { cause, recursion_depth, param_env, predicate }
})
}
pub fn predicate_for_trait_ref<'tcx>(
tcx: TyCtxt<'tcx>,
cause: ObligationCause<'tcx>,

View file

@ -711,7 +711,7 @@ impl<'tcx> WfPredicates<'tcx> {
iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev())
.map(|((mut pred, span), origin_def_id)| {
let code = if span.is_dummy() {
traits::MiscObligation
traits::ItemObligation(origin_def_id)
} else {
traits::BindingObligation(origin_def_id, span)
};