1
Fork 0

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`.
This commit is contained in:
Niko Matsakis 2018-10-03 10:07:16 -04:00
parent bf51840952
commit d4e4e374e7
2 changed files with 35 additions and 1 deletions

View file

@ -3666,8 +3666,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
closure_def_id: DefId,
substs: ty::ClosureSubsts<'tcx>,
) -> ty::PolyTraitRef<'tcx> {
debug!(
"closure_trait_ref_unnormalized(obligation={:?}, closure_def_id={:?}, substs={:?})",
obligation, closure_def_id, substs,
);
let closure_type = self.infcx.closure_sig(closure_def_id, substs);
debug!("closure_trait_ref_unnormalized: closure_type = {:?}", closure_type);
// (1) Feels icky to skip the binder here, but OTOH we know
// that the self-type is an unboxed closure type and hence is
// in fact unparameterized (or at least does not reference any

View file

@ -13,10 +13,12 @@
use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
use astconv::AstConv;
use middle::region;
use rustc::hir::def_id::DefId;
use rustc::infer::{InferOk, InferResult};
use rustc::infer::LateBoundRegionConversionTime;
use rustc::infer::type_variable::TypeVariableOrigin;
use rustc::traits::Obligation;
use rustc::traits::error_reporting::ArgKind;
use rustc::ty::{self, ToPolyTraitRef, Ty, GenericParamDefKind};
use rustc::ty::fold::TypeFoldable;
@ -479,7 +481,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Along the way, it also writes out entries for types that the user
// wrote into our tables, which are then later used by the privacy
// check.
match self.check_supplied_sig_against_expectation(expr_def_id, decl, &closure_sigs) {
match self.check_supplied_sig_against_expectation(expr_def_id, decl, body, &closure_sigs) {
Ok(infer_ok) => self.register_infer_ok_obligations(infer_ok),
Err(_) => return self.sig_of_closure_no_expectation(expr_def_id, decl, body),
}
@ -523,6 +525,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
&self,
expr_def_id: DefId,
decl: &hir::FnDecl,
body: &hir::Body,
expected_sigs: &ClosureSignatures<'tcx>,
) -> InferResult<'tcx, ()> {
// Get the signature S that the user gave.
@ -575,6 +578,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} = self.at(cause, self.param_env)
.eq(*expected_ty, supplied_ty)?;
all_obligations.extend(obligations);
// Also, require that the supplied type must outlive
// the closure body.
let closure_body_region = self.tcx.mk_region(
ty::ReScope(
region::Scope {
id: body.value.hir_id.local_id,
data: region::ScopeData::Node,
},
),
);
all_obligations.push(
Obligation::new(
cause.clone(),
self.param_env,
ty::Predicate::TypeOutlives(
ty::Binder::dummy(
ty::OutlivesPredicate(
supplied_ty,
closure_body_region,
),
),
),
),
);
}
let (supplied_output_ty, _) = self.infcx.replace_late_bound_regions_with_fresh_var(