Skip to content

Commit d4e4e37

Browse files
committed
apply minimum bounds when checking closure signature
Required for test expect-fn-supply-fn.rs to pass; otherwise we have unconstrained inference variables that get inferred to `'empty`.
1 parent bf51840 commit d4e4e37

File tree

2 files changed

+35
-1
lines changed

2 files changed

+35
-1
lines changed

src/librustc/traits/select.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3666,8 +3666,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
36663666
closure_def_id: DefId,
36673667
substs: ty::ClosureSubsts<'tcx>,
36683668
) -> ty::PolyTraitRef<'tcx> {
3669+
debug!(
3670+
"closure_trait_ref_unnormalized(obligation={:?}, closure_def_id={:?}, substs={:?})",
3671+
obligation, closure_def_id, substs,
3672+
);
36693673
let closure_type = self.infcx.closure_sig(closure_def_id, substs);
36703674

3675+
debug!("closure_trait_ref_unnormalized: closure_type = {:?}", closure_type);
3676+
36713677
// (1) Feels icky to skip the binder here, but OTOH we know
36723678
// that the self-type is an unboxed closure type and hence is
36733679
// in fact unparameterized (or at least does not reference any

src/librustc_typeck/check/closure.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
1414

1515
use astconv::AstConv;
16+
use middle::region;
1617
use rustc::hir::def_id::DefId;
1718
use rustc::infer::{InferOk, InferResult};
1819
use rustc::infer::LateBoundRegionConversionTime;
1920
use rustc::infer::type_variable::TypeVariableOrigin;
21+
use rustc::traits::Obligation;
2022
use rustc::traits::error_reporting::ArgKind;
2123
use rustc::ty::{self, ToPolyTraitRef, Ty, GenericParamDefKind};
2224
use rustc::ty::fold::TypeFoldable;
@@ -479,7 +481,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
479481
// Along the way, it also writes out entries for types that the user
480482
// wrote into our tables, which are then later used by the privacy
481483
// check.
482-
match self.check_supplied_sig_against_expectation(expr_def_id, decl, &closure_sigs) {
484+
match self.check_supplied_sig_against_expectation(expr_def_id, decl, body, &closure_sigs) {
483485
Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok),
484486
Err(_) => return self.sig_of_closure_no_expectation(expr_def_id, decl, body),
485487
}
@@ -523,6 +525,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
523525
&self,
524526
expr_def_id: DefId,
525527
decl: &hir::FnDecl,
528+
body: &hir::Body,
526529
expected_sigs: &ClosureSignatures<'tcx>,
527530
) -> InferResult<'tcx, ()> {
528531
// Get the signature S that the user gave.
@@ -575,6 +578,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
575578
} = self.at(cause, self.param_env)
576579
.eq(*expected_ty, supplied_ty)?;
577580
all_obligations.extend(obligations);
581+
582+
// Also, require that the supplied type must outlive
583+
// the closure body.
584+
let closure_body_region = self.tcx.mk_region(
585+
ty::ReScope(
586+
region::Scope {
587+
id: body.value.hir_id.local_id,
588+
data: region::ScopeData::Node,
589+
},
590+
),
591+
);
592+
all_obligations.push(
593+
Obligation::new(
594+
cause.clone(),
595+
self.param_env,
596+
ty::Predicate::TypeOutlives(
597+
ty::Binder::dummy(
598+
ty::OutlivesPredicate(
599+
supplied_ty,
600+
closure_body_region,
601+
),
602+
),
603+
),
604+
),
605+
);
578606
}
579607

580608
let (supplied_output_ty, _) = self.infcx.replace_late_bound_regions_with_fresh_var(

0 commit comments

Comments
 (0)