let ty = try!(self.node_ty(fn_node_id));
match ty.sty {
ty::ty_closure(closure_id, _, _) => {
- let kind = self.typer.closure_kind(closure_id);
- self.cat_upvar(id, span, var_id, fn_node_id, kind)
+ match self.typer.closure_kind(closure_id) {
+ Some(kind) => {
+ self.cat_upvar(id, span, var_id, fn_node_id, kind)
+ }
+ None => {
+ self.tcx().sess.span_bug(
+ span,
+ &*format!("No closure kind for {:?}", closure_id));
+ }
+ }
}
_ => {
self.tcx().sess.span_bug(
kind,
obligation.repr(self.tcx()));
- let closure_kind = self.closure_typer.closure_kind(closure_def_id);
-
- debug!("closure_kind = {:?}", closure_kind);
-
- if closure_kind == kind {
- candidates.vec.push(ClosureCandidate(closure_def_id, substs.clone()));
+ match self.closure_typer.closure_kind(closure_def_id) {
+ Some(closure_kind) => {
+ debug!("assemble_unboxed_candidates: closure_kind = {:?}", closure_kind);
+ if closure_kind == kind {
+ candidates.vec.push(ClosureCandidate(closure_def_id, substs.clone()));
+ }
+ }
+ None => {
+ debug!("assemble_unboxed_candidates: closure_kind not yet known");
+ candidates.ambiguous = true;
+ }
}
Ok(())
pub trait ClosureTyper<'tcx> {
fn param_env<'a>(&'a self) -> &'a ty::ParameterEnvironment<'a, 'tcx>;
- fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind;
-
+ /// Is this a `Fn`, `FnMut` or `FnOnce` closure? During typeck,
+ /// returns `None` if the kind of this closure has not yet been
+ /// inferred.
+ fn closure_kind(&self,
+ def_id: ast::DefId)
+ -> Option<ty::ClosureKind>;
+
+ /// Returns the argument/return types of this closure.
fn closure_type(&self,
def_id: ast::DefId,
substs: &subst::Substs<'tcx>)
-> ty::ClosureTy<'tcx>;
- // Returns `None` if the upvar types cannot yet be definitively determined.
+ /// Returns the set of all upvars and their transformed
+ /// types. During typeck, maybe return `None` if the upvar types
+ /// have not yet been inferred.
fn closure_upvars(&self,
def_id: ast::DefId,
substs: &Substs<'tcx>)
self
}
- fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
- self.tcx.closure_kind(def_id)
+ fn closure_kind(&self,
+ def_id: ast::DefId)
+ -> Option<ty::ClosureKind>
+ {
+ Some(self.tcx.closure_kind(def_id))
}
fn closure_type(&self,
&self.fcx.param_env
}
- fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
+ fn closure_kind(&self,
+ def_id: ast::DefId)
+ -> Option<ty::ClosureKind>
+ {
let typer = NormalizingClosureTyper::new(self.tcx());
typer.closure_kind(def_id)
}
&self.param_env
}
- fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
- self.param_env.tcx.closure_kind(def_id)
+ fn closure_kind(&self,
+ def_id: ast::DefId)
+ -> Option<ty::ClosureKind>
+ {
+ self.param_env.closure_kind(def_id)
}
fn closure_type(&self,
&self.inh.param_env
}
- fn closure_kind(&self, def_id: ast::DefId) -> ty::ClosureKind {
- self.inh.closures.borrow()[def_id].kind
+ fn closure_kind(&self,
+ def_id: ast::DefId)
+ -> Option<ty::ClosureKind>
+ {
+ Some(self.inh.closures.borrow()[def_id].kind)
}
fn closure_type(&self,