Skip to content

Commit cc65ebd

Browse files
committed
Make use of ObligationCtxt
1 parent aa7edf7 commit cc65ebd

File tree

2 files changed

+33
-54
lines changed

2 files changed

+33
-54
lines changed

compiler/rustc_hir_analysis/src/astconv/errors.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_data_structures::fx::FxHashMap;
44
use rustc_errors::{pluralize, struct_span_err, Applicability, Diagnostic, ErrorGuaranteed};
55
use rustc_hir as hir;
66
use rustc_hir::def_id::DefId;
7+
use rustc_infer::traits::FulfillmentError;
78
use rustc_middle::ty::{self, Ty};
89
use rustc_session::parse::feature_err;
910
use rustc_span::lev_distance::find_best_match_for_name;
@@ -226,8 +227,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
226227
&self,
227228
name: Ident,
228229
self_ty: Ty<'tcx>,
229-
candidates: &[DefId],
230-
unsatisfied_predicates: Vec<ty::Predicate<'tcx>>,
230+
candidates: Vec<(DefId, (DefId, DefId))>,
231+
fulfillment_errors: Vec<FulfillmentError<'tcx>>,
231232
span: Span,
232233
) -> ErrorGuaranteed {
233234
let tcx = self.tcx();
@@ -245,16 +246,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
245246
}
246247
};
247248

248-
if unsatisfied_predicates.is_empty() {
249+
if fulfillment_errors.is_empty() {
249250
// FIXME(fmease): Copied from `rustc_hir_typeck::method::probe`. Deduplicate.
250251

251252
let limit = if candidates.len() == 5 { 5 } else { 4 };
252253
let type_candidates = candidates
253254
.iter()
254255
.take(limit)
255-
.map(|candidate| {
256-
format!("- `{}`", tcx.at(span).type_of(candidate).subst_identity())
257-
})
256+
.map(|&(impl_, _)| format!("- `{}`", tcx.at(span).type_of(impl_).subst_identity()))
258257
.collect::<Vec<_>>()
259258
.join("\n");
260259
let additional_types = if candidates.len() > limit {
@@ -348,8 +347,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
348347

349348
// FIXME(fmease): `rustc_hir_typeck::method::suggest` uses a `skip_list` to filter out some bounds.
350349
// I would do the same here if it didn't mean more code duplication.
351-
let mut bounds: Vec<_> = unsatisfied_predicates
350+
let mut bounds: Vec<_> = fulfillment_errors
352351
.into_iter()
352+
.map(|error| error.root_obligation.predicate)
353353
.filter_map(format_pred)
354354
.map(|(p, _)| format!("`{}`", p))
355355
.collect();

compiler/rustc_hir_analysis/src/astconv/mod.rs

Lines changed: 26 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
2828
use rustc_hir::intravisit::{walk_generics, Visitor as _};
2929
use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
3030
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
31-
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
31+
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3232
use rustc_infer::traits::ObligationCause;
3333
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
3434
use rustc_middle::middle::stability::AllowUnstable;
@@ -42,13 +42,11 @@ use rustc_span::lev_distance::find_best_match_for_name;
4242
use rustc_span::symbol::{kw, Ident, Symbol};
4343
use rustc_span::{sym, Span, DUMMY_SP};
4444
use rustc_target::spec::abi;
45-
use rustc_trait_selection::traits;
4645
use rustc_trait_selection::traits::error_reporting::{
4746
report_object_safety_error, suggestions::NextTypeParamName,
4847
};
49-
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
5048
use rustc_trait_selection::traits::wf::object_region_bounds;
51-
use rustc_trait_selection::traits::{astconv_object_safety_violations, NormalizeExt};
49+
use rustc_trait_selection::traits::{self, astconv_object_safety_violations, ObligationCtxt};
5250

5351
use smallvec::{smallvec, SmallVec};
5452
use std::collections::BTreeSet;
@@ -1948,7 +1946,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
19481946
Res::Err
19491947
};
19501948

1951-
// Check if we have an enum variant.
1949+
// Check if we have an enum variant or an inherent associated type.
19521950
let mut variant_resolution = None;
19531951
if let Some(adt_def) = self.probe_adt(span, qself_ty) {
19541952
if adt_def.is_enum() {
@@ -2221,62 +2219,37 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22212219

22222220
let param_env = tcx.param_env(block.owner.to_def_id());
22232221
let cause = ObligationCause::misc(span, block.owner.def_id);
2224-
let mut unsatisfied_predicates = Vec::new();
2222+
let mut fulfillment_errors = Vec::new();
22252223

22262224
for &(impl_, (assoc_item, def_scope)) in &candidates {
22272225
let infcx = tcx.infer_ctxt().ignoring_regions().build();
2226+
let ocx = ObligationCtxt::new(&infcx);
22282227

22292228
let impl_ty = tcx.type_of(impl_);
22302229
let impl_substs = self.fresh_item_substs(impl_, &infcx);
22312230
let impl_ty = impl_ty.subst(tcx, impl_substs);
2232-
2233-
let InferOk { value: impl_ty, obligations } =
2234-
infcx.at(&cause, param_env).normalize(impl_ty);
2231+
let impl_ty = ocx.normalize(&cause, param_env, impl_ty);
22352232

22362233
// Check that the Self-types can be related.
2237-
let Ok(InferOk { obligations: sub_obligations, value: () }) = infcx
2238-
.at(&ObligationCause::dummy(), param_env)
2239-
.define_opaque_types(false)
2240-
.sup(impl_ty, self_ty)
2241-
else {
2234+
// FIXME(fmease): Should we use `eq` here?
2235+
if ocx.sup(&ObligationCause::dummy(), param_env, impl_ty, self_ty).is_err() {
22422236
continue;
2243-
};
2237+
}
22442238

22452239
// Check whether the impl imposes obligations we have to worry about.
22462240
let impl_bounds = tcx.predicates_of(impl_);
22472241
let impl_bounds = impl_bounds.instantiate(tcx, impl_substs);
22482242

2249-
let InferOk { value: impl_bounds, obligations: norm_obligations } =
2250-
infcx.at(&cause, param_env).normalize(impl_bounds);
2243+
let impl_bounds = ocx.normalize(&cause, param_env, impl_bounds);
22512244

22522245
let impl_obligations =
22532246
traits::predicates_for_generics(|_, _| cause.clone(), param_env, impl_bounds);
22542247

2255-
let candidate_obligations = impl_obligations
2256-
.chain(norm_obligations.into_iter())
2257-
.chain(obligations.iter().cloned());
2258-
2259-
let mut matches = true;
2260-
2261-
// Evaluate those obligations to see if they might possibly hold.
2262-
for o in candidate_obligations {
2263-
let o = infcx.resolve_vars_if_possible(o);
2264-
if !infcx.predicate_may_hold(&o) {
2265-
matches = false;
2266-
unsatisfied_predicates.push(o.predicate);
2267-
}
2268-
}
2248+
ocx.register_obligations(impl_obligations);
22692249

2270-
// Evaluate those obligations to see if they might possibly hold.
2271-
for o in sub_obligations {
2272-
let o = infcx.resolve_vars_if_possible(o);
2273-
if !infcx.predicate_may_hold(&o) {
2274-
matches = false;
2275-
unsatisfied_predicates.push(o.predicate);
2276-
}
2277-
}
2278-
2279-
if !matches {
2250+
let errors = ocx.select_where_possible();
2251+
if !errors.is_empty() {
2252+
fulfillment_errors = errors;
22802253
continue;
22812254
}
22822255

@@ -2286,19 +2259,25 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
22862259
bug!("unreachable: `lookup_inherent_assoc_ty` is only called on ADTs");
22872260
};
22882261

2289-
let item_substs =
2290-
self.create_substs_for_associated_item(span, assoc_item, segment, adt_substs);
2291-
// FIXME(inherent_associated_types): Check if the obligations arising from the
2292-
// where-clause & the bounds on the associated type and its parameters hold.
2262+
let item_substs = self.create_substs_for_associated_item(
2263+
span, assoc_item, segment,
2264+
// FIXME(fmease, #107468, #105305): Don't use `adt_substs` here but `impl_substs`.
2265+
adt_substs,
2266+
);
2267+
2268+
// FIXME(fmease, #106722): Check if the bounds on the parameters of the
2269+
// associated type hold, if any.
22932270
let ty = tcx.type_of(assoc_item).subst(tcx, item_substs);
2271+
2272+
// FIXME(fmease): Don't return early here! There might be multiple applicable candidates.
22942273
return Ok(Some((ty, assoc_item)));
22952274
}
22962275

22972276
Err(self.complain_about_inherent_assoc_type_not_found(
22982277
name,
22992278
self_ty,
2300-
&candidates.into_iter().map(|(impl_, _)| impl_).collect::<Vec<_>>(),
2301-
unsatisfied_predicates,
2279+
candidates,
2280+
fulfillment_errors,
23022281
span,
23032282
))
23042283
}

0 commit comments

Comments
 (0)