Skip to content

Commit a96bce7

Browse files
committed
avoid using skip_binder and instead look for bound vars properly
1 parent 3f277e1 commit a96bce7

File tree

1 file changed

+25
-12
lines changed

1 file changed

+25
-12
lines changed

src/librustc_typeck/check/closure.rs

+25-12
Original file line numberDiff line numberDiff line change
@@ -698,39 +698,52 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
698698

699699
/// Given a projection like
700700
///
701-
/// `<_ as Future>::Output = T`
701+
/// `<X as Future>::Output = T`
702702
///
703-
/// returns `Some(T)`. If the projection is for some other trait,
704-
/// returns `None`.
703+
/// where `X` is some type that has no late-bound regions, returns
704+
/// `Some(T)`. If the projection is for some other trait, returns
705+
/// `None`.
705706
fn deduce_future_output_from_projection(
706707
&self,
707708
cause_span: Span,
708-
projection: &ty::PolyProjectionPredicate<'tcx>,
709+
predicate: &ty::PolyProjectionPredicate<'tcx>,
709710
) -> Option<Ty<'tcx>> {
710-
debug!("deduce_future_output_from_projection(projection={:?})", projection);
711+
debug!("deduce_future_output_from_projection(predicate={:?})", predicate);
712+
713+
// We do not expect any bound regions in our predicate, so
714+
// skip past the bound vars.
715+
let predicate = match predicate.no_bound_vars() {
716+
Some(p) => p,
717+
None => {
718+
debug!("deduce_future_output_from_projection: has late-bound regions");
719+
return None;
720+
}
721+
};
711722

712-
let trait_ref = projection.to_poly_trait_ref(self.tcx);
723+
// Check that this is a projection from the `Future` trait.
724+
let trait_ref = predicate.projection_ty.trait_ref(self.tcx);
713725
let future_trait = self.tcx.lang_items().future_trait().unwrap();
714-
if trait_ref.def_id() != future_trait {
726+
if trait_ref.def_id != future_trait {
715727
debug!("deduce_future_output_from_projection: not a future");
716728
return None;
717729
}
718730

719731
// The `Future` trait has only one associted item, `Output`,
720732
// so check that this is what we see.
721733
let output_assoc_item = self.tcx.associated_items(future_trait).nth(0).unwrap().def_id;
722-
if output_assoc_item != projection.projection_def_id() {
734+
if output_assoc_item != predicate.projection_ty.item_def_id {
723735
span_bug!(
724736
cause_span,
725737
"projecting associated item `{:?}` from future, which is not Output `{:?}`",
726-
projection.projection_def_id(),
738+
predicate.projection_ty.item_def_id,
727739
output_assoc_item,
728740
);
729741
}
730742

731-
// Extract the type from the projection.
732-
let output_ty = projection.skip_binder().ty;
733-
let output_ty = self.resolve_vars_if_possible(&output_ty);
743+
// Extract the type from the projection. Note that there can
744+
// be no bound variables in this type because the "self type"
745+
// does not have any regions in it.
746+
let output_ty = self.resolve_vars_if_possible(&predicate.ty);
734747
debug!("deduce_future_output_from_projection: output_ty={:?}", output_ty);
735748
Some(output_ty)
736749
}

0 commit comments

Comments
 (0)