Skip to content

Commit 24d4f10

Browse files
committed
change to use higher_ranked_match
also, consolidate the return type into from a tuple into a struct `Progress`
1 parent 21eb366 commit 24d4f10

File tree

2 files changed

+90
-60
lines changed

2 files changed

+90
-60
lines changed

src/librustc/infer/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,7 +1619,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
16191619
origin: TypeOrigin,
16201620
match_a: ty::PolyProjectionPredicate<'tcx>,
16211621
match_b: ty::TraitRef<'tcx>)
1622-
-> RelateResult<HrMatchResult<Ty<'tcx>>>
1622+
-> InferResult<'tcx, HrMatchResult<Ty<'tcx>>>
16231623
{
16241624
let span = origin.span();
16251625
let match_trait_ref = match_a.skip_binder().projection_ty.trait_ref;
@@ -1629,8 +1629,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
16291629
};
16301630

16311631
let match_pair = match_a.map_bound(|p| (p.projection_ty.trait_ref, p.ty));
1632-
self.combine_fields(true, trace)
1633-
.higher_ranked_match(span, &match_pair, &match_b)
1632+
let combine = self.combine_fields(true, trace);
1633+
let result = combine.higher_ranked_match(span, &match_pair, &match_b)?;
1634+
Ok(InferOk { value: result, obligations: combine.obligations })
16341635
}
16351636

16361637
/// See `verify_generic_bound` method in `region_inference`

src/librustc/traits/project.rs

Lines changed: 86 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use infer::{self, InferOk, TypeOrigin};
2828
use ty::subst::Subst;
2929
use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt};
3030
use ty::fold::{TypeFoldable, TypeFolder};
31+
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
3132
use syntax::parse::token;
3233
use syntax::ast;
3334
use util::common::FN_OUTPUT_NAME;
@@ -424,19 +425,25 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
424425

425426
let obligation = Obligation::with_depth(cause.clone(), depth, projection_ty.clone());
426427
match project_type(selcx, &obligation) {
427-
Ok(ProjectedTy::Progress(projected_ty, mut obligations)) => {
428+
Ok(ProjectedTy::Progress(Progress { ty: projected_ty,
429+
mut obligations,
430+
cacheable })) => {
428431
// if projection succeeded, then what we get out of this
429432
// is also non-normalized (consider: it was derived from
430433
// an impl, where-clause etc) and hence we must
431434
// re-normalize it
432435

433436
debug!("opt_normalize_projection_type: \
434-
projected_ty={:?} depth={} obligations={:?}",
437+
projected_ty={:?} \
438+
depth={} \
439+
obligations={:?} \
440+
cacheable={:?}",
435441
projected_ty,
436442
depth,
437-
obligations);
443+
obligations,
444+
cacheable);
438445

439-
if projected_ty.has_projection_types() {
446+
let result = if projected_ty.has_projection_types() {
440447
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth+1);
441448
let normalized_ty = normalizer.fold(&projected_ty);
442449

@@ -455,7 +462,9 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
455462
value: projected_ty,
456463
obligations: obligations,
457464
})
458-
}
465+
};
466+
467+
result
459468
}
460469
Ok(ProjectedTy::NoProgress(projected_ty)) => {
461470
debug!("opt_normalize_projection_type: \
@@ -520,11 +529,37 @@ fn normalize_to_error<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 'tc
520529
}
521530

522531
enum ProjectedTy<'tcx> {
523-
Progress(Ty<'tcx>, Vec<PredicateObligation<'tcx>>),
532+
Progress(Progress<'tcx>),
524533
NoProgress(Ty<'tcx>),
525534
}
526535

536+
struct Progress<'tcx> {
537+
ty: Ty<'tcx>,
538+
obligations: Vec<PredicateObligation<'tcx>>,
539+
cacheable: bool,
540+
}
541+
542+
impl<'tcx> Progress<'tcx> {
543+
fn error<'a,'gcx>(tcx: TyCtxt<'a,'gcx,'tcx>) -> Self {
544+
Progress {
545+
ty: tcx.types.err,
546+
obligations: vec![],
547+
cacheable: true
548+
}
549+
}
550+
551+
fn with_addl_obligations(mut self,
552+
mut obligations: Vec<PredicateObligation<'tcx>>)
553+
-> Self {
554+
self.obligations.append(&mut obligations);
555+
self
556+
}
557+
}
558+
527559
/// Compute the result of a projection type (if we can).
560+
///
561+
/// IMPORTANT:
562+
/// - `obligation` must be fully normalized
528563
fn project_type<'cx, 'gcx, 'tcx>(
529564
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
530565
obligation: &ProjectionTyObligation<'tcx>)
@@ -539,13 +574,12 @@ fn project_type<'cx, 'gcx, 'tcx>(
539574
selcx.infcx().report_overflow_error(&obligation, true);
540575
}
541576

542-
let obligation_trait_ref =
543-
selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate.trait_ref);
577+
let obligation_trait_ref = &obligation.predicate.trait_ref;
544578

545579
debug!("project: obligation_trait_ref={:?}", obligation_trait_ref);
546580

547581
if obligation_trait_ref.references_error() {
548-
return Ok(ProjectedTy::Progress(selcx.tcx().types.err, vec!()));
582+
return Ok(ProjectedTy::Progress(Progress::error(selcx.tcx())));
549583
}
550584

551585
let mut candidates = ProjectionTyCandidateSet {
@@ -623,16 +657,17 @@ fn project_type<'cx, 'gcx, 'tcx>(
623657

624658
match candidates.vec.pop() {
625659
Some(candidate) => {
626-
let (ty, obligations) = confirm_candidate(selcx,
627-
obligation,
628-
&obligation_trait_ref,
629-
candidate);
630-
Ok(ProjectedTy::Progress(ty, obligations))
660+
Ok(ProjectedTy::Progress(
661+
confirm_candidate(selcx,
662+
obligation,
663+
&obligation_trait_ref,
664+
candidate)))
631665
}
632666
None => {
633-
Ok(ProjectedTy::NoProgress(selcx.tcx().mk_projection(
634-
obligation.predicate.trait_ref.clone(),
635-
obligation.predicate.item_name)))
667+
Ok(ProjectedTy::NoProgress(
668+
selcx.tcx().mk_projection(
669+
obligation.predicate.trait_ref.clone(),
670+
obligation.predicate.item_name)))
636671
}
637672
}
638673
}
@@ -935,7 +970,7 @@ fn confirm_candidate<'cx, 'gcx, 'tcx>(
935970
obligation: &ProjectionTyObligation<'tcx>,
936971
obligation_trait_ref: &ty::TraitRef<'tcx>,
937972
candidate: ProjectionTyCandidate<'tcx>)
938-
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
973+
-> Progress<'tcx>
939974
{
940975
debug!("confirm_candidate(candidate={:?}, obligation={:?})",
941976
candidate,
@@ -957,7 +992,7 @@ fn confirm_select_candidate<'cx, 'gcx, 'tcx>(
957992
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
958993
obligation: &ProjectionTyObligation<'tcx>,
959994
obligation_trait_ref: &ty::TraitRef<'tcx>)
960-
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
995+
-> Progress<'tcx>
961996
{
962997
let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
963998
let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
@@ -995,7 +1030,7 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
9951030
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
9961031
obligation: &ProjectionTyObligation<'tcx>,
9971032
obligation_trait_ref: &ty::TraitRef<'tcx>)
998-
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
1033+
-> Progress<'tcx>
9991034
{
10001035
let self_ty = obligation_trait_ref.self_ty();
10011036
let object_ty = selcx.infcx().shallow_resolve(self_ty);
@@ -1007,7 +1042,7 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
10071042
span_bug!(
10081043
obligation.cause.span,
10091044
"confirm_object_candidate called with non-object: {:?}",
1010-
object_ty);
1045+
object_ty)
10111046
}
10121047
};
10131048
let projection_bounds = data.projection_bounds_with_self_ty(selcx.tcx(), object_ty);
@@ -1051,7 +1086,7 @@ fn confirm_object_candidate<'cx, 'gcx, 'tcx>(
10511086
debug!("confirm_object_candidate: no env-predicate \
10521087
found in object type `{:?}`; ill-formed",
10531088
object_ty);
1054-
return (selcx.tcx().types.err, vec!());
1089+
return Progress::error(selcx.tcx());
10551090
}
10561091
}
10571092
};
@@ -1063,7 +1098,7 @@ fn confirm_fn_pointer_candidate<'cx, 'gcx, 'tcx>(
10631098
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
10641099
obligation: &ProjectionTyObligation<'tcx>,
10651100
fn_pointer_vtable: VtableFnPointerData<'tcx, PredicateObligation<'tcx>>)
1066-
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
1101+
-> Progress<'tcx>
10671102
{
10681103
// FIXME(#32730) drop this assertion once obligations are propagated from inference (fn pointer
10691104
// vtable nested obligations ONLY come from unification in inference)
@@ -1077,31 +1112,30 @@ fn confirm_closure_candidate<'cx, 'gcx, 'tcx>(
10771112
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
10781113
obligation: &ProjectionTyObligation<'tcx>,
10791114
vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>)
1080-
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
1115+
-> Progress<'tcx>
10811116
{
10821117
let closure_typer = selcx.closure_typer();
10831118
let closure_type = closure_typer.closure_type(vtable.closure_def_id, vtable.substs);
10841119
let Normalized {
10851120
value: closure_type,
1086-
mut obligations
1121+
obligations
10871122
} = normalize_with_depth(selcx,
10881123
obligation.cause.clone(),
10891124
obligation.recursion_depth+1,
10901125
&closure_type);
1091-
let (ty, mut cc_obligations) = confirm_callable_candidate(selcx,
1092-
obligation,
1093-
&closure_type.sig,
1094-
util::TupleArgumentsFlag::No);
1095-
obligations.append(&mut cc_obligations);
1096-
(ty, obligations)
1126+
confirm_callable_candidate(selcx,
1127+
obligation,
1128+
&closure_type.sig,
1129+
util::TupleArgumentsFlag::No)
1130+
.with_addl_obligations(obligations)
10971131
}
10981132

10991133
fn confirm_callable_candidate<'cx, 'gcx, 'tcx>(
11001134
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
11011135
obligation: &ProjectionTyObligation<'tcx>,
11021136
fn_sig: &ty::PolyFnSig<'tcx>,
11031137
flag: util::TupleArgumentsFlag)
1104-
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
1138+
-> Progress<'tcx>
11051139
{
11061140
let tcx = selcx.tcx();
11071141

@@ -1134,47 +1168,38 @@ fn confirm_param_env_candidate<'cx, 'gcx, 'tcx>(
11341168
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
11351169
obligation: &ProjectionTyObligation<'tcx>,
11361170
poly_projection: ty::PolyProjectionPredicate<'tcx>)
1137-
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
1171+
-> Progress<'tcx>
11381172
{
11391173
let infcx = selcx.infcx();
1140-
1141-
let projection =
1142-
infcx.replace_late_bound_regions_with_fresh_var(
1143-
obligation.cause.span,
1144-
infer::LateBoundRegionConversionTime::HigherRankedType,
1145-
&poly_projection).0;
1146-
1147-
assert_eq!(projection.projection_ty.item_name,
1148-
obligation.predicate.item_name);
1149-
11501174
let origin = TypeOrigin::RelateOutputImplTypes(obligation.cause.span);
1151-
let obligations = match infcx.eq_trait_refs(false,
1152-
origin,
1153-
obligation.predicate.trait_ref.clone(),
1154-
projection.projection_ty.trait_ref.clone()) {
1155-
Ok(InferOk { obligations, .. }) => {
1156-
// FIXME(#32730) once obligations are generated in inference, remove this assertion
1175+
let trait_ref = obligation.predicate.trait_ref;
1176+
match infcx.match_poly_projection_predicate(origin, poly_projection, trait_ref) {
1177+
Ok(InferOk { value: ty_match, obligations }) => {
1178+
// FIXME(#32730) once obligations are generated in inference, drop this assertion
11571179
assert!(obligations.is_empty());
1158-
obligations
1180+
Progress {
1181+
ty: ty_match.value,
1182+
obligations: obligations,
1183+
cacheable: ty_match.unconstrained_regions.is_empty(),
1184+
}
11591185
}
11601186
Err(e) => {
11611187
span_bug!(
11621188
obligation.cause.span,
1163-
"Failed to unify `{:?}` and `{:?}` in projection: {}",
1189+
"Failed to unify obligation `{:?}` \
1190+
with poly_projection `{:?}`: {:?}",
11641191
obligation,
1165-
projection,
1192+
poly_projection,
11661193
e);
11671194
}
1168-
};
1169-
1170-
(projection.ty, obligations)
1195+
}
11711196
}
11721197

11731198
fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
11741199
selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
11751200
obligation: &ProjectionTyObligation<'tcx>,
11761201
impl_vtable: VtableImplData<'tcx, PredicateObligation<'tcx>>)
1177-
-> (Ty<'tcx>, Vec<PredicateObligation<'tcx>>)
1202+
-> Progress<'tcx>
11781203
{
11791204
let VtableImplData { substs, nested, impl_def_id } = impl_vtable;
11801205

@@ -1195,7 +1220,11 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
11951220
tcx.types.err
11961221
});
11971222
let substs = translate_substs(selcx.infcx(), impl_def_id, substs, node_item.node);
1198-
(ty.subst(tcx, substs), nested)
1223+
Progress {
1224+
ty: ty.subst(tcx, substs),
1225+
obligations: nested,
1226+
cacheable: true
1227+
}
11991228
}
12001229
None => {
12011230
span_bug!(obligation.cause.span,

0 commit comments

Comments
 (0)