Skip to content

Commit 6487845

Browse files
committed
Properly account for binders in get_impl_future_output_ty
1 parent 5e57faa commit 6487845

File tree

4 files changed

+31
-20
lines changed

4 files changed

+31
-20
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+18-11
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ use rustc_middle::ty::error::TypeError;
6969
use rustc_middle::ty::{
7070
self,
7171
subst::{GenericArgKind, Subst, SubstsRef},
72-
Region, Ty, TyCtxt, TypeFoldable,
72+
Binder, Region, Ty, TyCtxt, TypeFoldable,
7373
};
7474
use rustc_span::{sym, BytePos, DesugaringKind, MultiSpan, Pos, Span};
7575
use rustc_target::spec::abi;
@@ -1765,7 +1765,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
17651765
self.note_error_origin(diag, cause, exp_found, terr);
17661766
}
17671767

1768-
pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Ty<'tcx>> {
1768+
pub fn get_impl_future_output_ty(&self, ty: Ty<'tcx>) -> Option<Binder<'tcx, Ty<'tcx>>> {
17691769
if let ty::Opaque(def_id, substs) = ty.kind() {
17701770
let future_trait = self.tcx.require_lang_item(LangItem::Future, None);
17711771
// Future::Output
@@ -1775,13 +1775,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
17751775

17761776
for (predicate, _) in bounds {
17771777
let predicate = predicate.subst(self.tcx, substs);
1778-
if let ty::PredicateKind::Projection(projection_predicate) =
1779-
predicate.kind().skip_binder()
1780-
{
1781-
if projection_predicate.projection_ty.item_def_id == item_def_id {
1782-
// We don't account for multiple `Future::Output = Ty` contraints.
1783-
return projection_predicate.term.ty();
1784-
}
1778+
let output = predicate
1779+
.kind()
1780+
.map_bound(|kind| match kind {
1781+
ty::PredicateKind::Projection(projection_predicate)
1782+
if projection_predicate.projection_ty.item_def_id == item_def_id =>
1783+
{
1784+
projection_predicate.term.ty()
1785+
}
1786+
_ => None,
1787+
})
1788+
.transpose();
1789+
if output.is_some() {
1790+
// We don't account for multiple `Future::Output = Ty` contraints.
1791+
return output;
17851792
}
17861793
}
17871794
}
@@ -1823,8 +1830,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
18231830
}
18241831

18251832
match (
1826-
self.get_impl_future_output_ty(exp_found.expected),
1827-
self.get_impl_future_output_ty(exp_found.found),
1833+
self.get_impl_future_output_ty(exp_found.expected).map(Binder::skip_binder),
1834+
self.get_impl_future_output_ty(exp_found.found).map(Binder::skip_binder),
18281835
) {
18291836
(Some(exp), Some(found)) if same_type_modulo_infer(exp, found) => match cause.code() {
18301837
ObligationCauseCode::IfExpression(box IfExpressionCause { then, .. }) => {

compiler/rustc_typeck/src/check/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1909,7 +1909,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
19091909
_ => return,
19101910
};
19111911
let mut add_label = true;
1912-
if let ty::Adt(def, _) = output_ty.kind() {
1912+
if let ty::Adt(def, _) = output_ty.skip_binder().kind() {
19131913
// no field access on enum type
19141914
if !def.is_enum() {
19151915
if def

compiler/rustc_typeck/src/check/fn_ctxt/suggestions.rs

+11-7
Original file line numberDiff line numberDiff line change
@@ -609,14 +609,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
609609
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
610610
let ty = self.normalize_associated_types_in(expr.span, ty);
611611
let ty = match self.tcx.asyncness(fn_id.owner) {
612-
hir::IsAsync::Async => self.tcx.infer_ctxt().enter(|infcx| {
613-
infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| {
614-
span_bug!(
615-
fn_decl.output.span(),
616-
"failed to get output type of async function"
617-
)
612+
hir::IsAsync::Async => self
613+
.tcx
614+
.infer_ctxt()
615+
.enter(|infcx| {
616+
infcx.get_impl_future_output_ty(ty).unwrap_or_else(|| {
617+
span_bug!(
618+
fn_decl.output.span(),
619+
"failed to get output type of async function"
620+
)
621+
})
618622
})
619-
}),
623+
.skip_binder(),
620624
hir::IsAsync::NotAsync => ty,
621625
};
622626
if self.can_coerce(found, ty) {

compiler/rustc_typeck/src/check/method/suggest.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
12741274
span: Span,
12751275
) {
12761276
let output_ty = match self.infcx.get_impl_future_output_ty(ty) {
1277-
Some(output_ty) => self.resolve_vars_if_possible(output_ty),
1277+
Some(output_ty) => self.resolve_vars_if_possible(output_ty).skip_binder(),
12781278
_ => return,
12791279
};
12801280
let method_exists = self.method_exists(item_name, output_ty, call.hir_id, true);

0 commit comments

Comments
 (0)