Make unboxed_closure_kind return Option to allow for the possibility that its value is not yet known.

This commit is contained in:
Niko Matsakis 2015-01-26 06:22:06 -05:00
parent 53c1956cfb
commit bc41cc0ec9
5 changed files with 50 additions and 17 deletions

View file

@ -594,8 +594,16 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
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(

View file

@ -1024,12 +1024,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
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(())

View file

@ -2288,14 +2288,22 @@ impl ClosureKind {
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>)
@ -6473,8 +6481,11 @@ impl<'a,'tcx> ClosureTyper<'tcx> for ty::ParameterEnvironment<'a,'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,

View file

@ -693,7 +693,10 @@ impl<'blk, 'tcx> ty::ClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
&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)
}
@ -1065,8 +1068,11 @@ impl<'a,'tcx> ty::ClosureTyper<'tcx> for NormalizingClosureTyper<'a,'tcx> {
&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,

View file

@ -348,8 +348,11 @@ impl<'a, 'tcx> ty::ClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
&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,