closure_kind_ty.to_opt_closure_kind()
}
- /// Obtain the signature of a function or closure.
- /// For closures, unlike `tcx.fn_sig(def_id)`, this method will
- /// work during the type-checking of the enclosing function and
- /// return the closure signature in its partially inferred state.
- pub fn fn_sig(&self, def_id: DefId) -> ty::PolyFnSig<'tcx> {
- // Do we have an in-progress set of tables we are inferring?
- if let Some(tables) = self.in_progress_tables {
- // Is this a local item?
- if let Some(id) = self.tcx.hir.as_local_node_id(def_id) {
- // Is it a local *closure*?
- if self.tcx.is_closure(def_id) {
- let hir_id = self.tcx.hir.node_to_hir_id(id);
- // Is this local closure contained within the tables we are inferring?
- if tables.borrow().local_id_root == Some(DefId::local(hir_id.owner)) {
- // if so, extract signature from there.
- let closure_ty = tables.borrow().node_id_to_type(hir_id);
- let (closure_def_id, closure_substs) = match closure_ty.sty {
- ty::TyClosure(closure_def_id, closure_substs) =>
- (closure_def_id, closure_substs),
- _ =>
- bug!("closure with non-closure type: {:?}", closure_ty),
- };
- assert_eq!(def_id, closure_def_id);
- let closure_sig_ty = closure_substs.closure_sig_ty(def_id, self.tcx);
- let closure_sig_ty = self.shallow_resolve(&closure_sig_ty);
- return closure_sig_ty.fn_sig(self.tcx);
- }
- }
- }
- }
-
- self.tcx.fn_sig(def_id)
+ /// Obtain the signature of a closure. For closures, unlike
+ /// `tcx.fn_sig(def_id)`, this method will work during the
+ /// type-checking of the enclosing function and return the closure
+ /// signature in its partially inferred state.
+ pub fn closure_sig(
+ &self,
+ def_id: DefId,
+ substs: ty::ClosureSubsts<'tcx>
+ ) -> ty::PolyFnSig<'tcx> {
+ let closure_sig_ty = substs.closure_sig_ty(def_id, self.tcx);
+ let closure_sig_ty = self.shallow_resolve(&closure_sig_ty);
+ closure_sig_ty.fn_sig(self.tcx)
}
/// Normalizes associated types in `value`, potentially returning
vtable: VtableClosureData<'tcx, PredicateObligation<'tcx>>)
-> Progress<'tcx>
{
- let closure_typer = selcx.closure_typer();
- let closure_type = closure_typer.fn_sig(vtable.closure_def_id)
- .subst(selcx.tcx(), vtable.substs.substs);
+ let tcx = selcx.tcx();
+ let infcx = selcx.infcx();
+ let closure_sig_ty = vtable.substs.closure_sig_ty(vtable.closure_def_id, tcx);
+ let closure_sig = infcx.shallow_resolve(&closure_sig_ty).fn_sig(tcx);
let Normalized {
- value: closure_type,
+ value: closure_sig,
obligations
} = normalize_with_depth(selcx,
obligation.param_env,
obligation.cause.clone(),
obligation.recursion_depth+1,
- &closure_type);
+ &closure_sig);
- debug!("confirm_closure_candidate: obligation={:?},closure_type={:?},obligations={:?}",
+ debug!("confirm_closure_candidate: obligation={:?},closure_sig={:?},obligations={:?}",
obligation,
- closure_type,
+ closure_sig,
obligations);
confirm_callable_candidate(selcx,
obligation,
- closure_type,
+ closure_sig,
util::TupleArgumentsFlag::No)
.with_addl_obligations(vtable.nested)
.with_addl_obligations(obligations)
substs: ty::ClosureSubsts<'tcx>)
-> ty::PolyTraitRef<'tcx>
{
- let closure_type = self.infcx.fn_sig(closure_def_id)
- .subst(self.tcx(), substs.substs);
+ let closure_type = self.infcx.closure_sig(closure_def_id, substs);
let ty::Binder((trait_ref, _)) =
self.tcx().closure_trait_ref_and_return_type(obligation.predicate.def_id(),
obligation.predicate.0.self_ty(), // (1)
/// Returns the closure kind for this closure; only usable outside
/// of an inference context, because in that context we know that
/// there are no type variables.
+ ///
+ /// If you have an inference context, use `infcx.closure_kind()`.
pub fn closure_kind(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::ClosureKind {
self.split(def_id, tcx).closure_kind_ty.to_opt_closure_kind().unwrap()
}
/// Extracts the signature from the closure; only usable outside
/// of an inference context, because in that context we know that
/// there are no type variables.
+ ///
+ /// If you have an inference context, use `infcx.closure_sig()`.
pub fn closure_sig(self, def_id: DefId, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> ty::PolyFnSig<'tcx> {
match self.closure_sig_ty(def_id, tcx).sty {
ty::TyFnPtr(sig) => sig,
impl<'cx, 'gcx, 'tcx> UniversalRegionsBuilder<'cx, 'gcx, 'tcx> {
fn build(mut self) -> UniversalRegions<'tcx> {
+ debug!("build(mir_def_id={:?})", self.mir_def_id);
+
let param_env = self.param_env;
+ debug!("build: param_env={:?}", param_env);
assert_eq!(FIRST_GLOBAL_INDEX, self.infcx.num_region_vars());
let first_extern_index = self.infcx.num_region_vars();
let defining_ty = self.defining_ty();
+ debug!("build: defining_ty={:?}", defining_ty);
let indices = self.compute_indices(fr_static, defining_ty);
+ debug!("build: indices={:?}", indices);
let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
// Add the implied bounds from inputs and outputs.
for ty in inputs_and_output {
+ debug!("build: input_or_output={:?}", ty);
self.add_implied_bounds(&indices, ty);
}
// Finally, outlives is reflexive, and static outlives every
// other free region.
for fr in (FIRST_GLOBAL_INDEX..num_universals).map(RegionVid::new) {
+ debug!("build: relating free region {:?} to itself and to 'static", fr);
self.relations.relate_universal_regions(fr, fr);
self.relations.relate_universal_regions(fr_static, fr);
}
///
/// Assumes that `universal_regions` indices map is fully constructed.
fn add_implied_bounds(&mut self, indices: &UniversalRegionIndices<'tcx>, ty: Ty<'tcx>) {
+ debug!("add_implied_bounds(ty={:?})", ty);
let span = self.infcx.tcx.def_span(self.mir_def_id);
let bounds = self.infcx
.implied_outlives_bounds(self.param_env, self.mir_node_id, ty, span);
I: IntoIterator<Item = OutlivesBound<'tcx>>,
{
for outlives_bound in outlives_bounds {
+ debug!("add_outlives_bounds(bound={:?})", outlives_bound);
+
match outlives_bound {
OutlivesBound::RegionSubRegion(r1, r2) => {
// The bound says that `r1 <= r2`; we store `r2: r1`.
use hir::def_id::{DefId, LOCAL_CRATE};
use rustc::{infer, traits};
use rustc::ty::{self, TyCtxt, TypeFoldable, LvaluePreference, Ty};
-use rustc::ty::subst::Subst;
use rustc::ty::adjustment::{Adjustment, Adjust, AutoBorrow};
use syntax::abi;
use syntax::symbol::Symbol;
// haven't yet decided on whether the closure is fn vs
// fnmut vs fnonce. If so, we have to defer further processing.
if self.closure_kind(def_id, substs).is_none() {
- let closure_ty = self.fn_sig(def_id).subst(self.tcx, substs.substs);
+ let closure_ty = self.closure_sig(def_id, substs);
let fn_sig = self.replace_late_bound_regions_with_fresh_var(call_expr.span,
infer::FnCall,
&closure_ty)
use rustc::ty::fold::TypeFoldable;
use rustc::ty::error::TypeError;
use rustc::ty::relate::RelateResult;
-use rustc::ty::subst::Subst;
use errors::DiagnosticBuilder;
use syntax::abi;
use syntax::feature_gate;
// `extern "rust-call" fn((arg0,arg1,...)) -> _`
// to
// `fn(arg0,arg1,...) -> _`
- let sig = self.fn_sig(def_id_a).subst(self.tcx, substs_a.substs);
+ let sig = self.closure_sig(def_id_a, substs_a);
let converted_sig = sig.map_bound(|s| {
let params_iter = match s.inputs()[0].sty {
ty::TyTuple(params, _) => {