mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-21 17:52:12 +03:00
auto merge of #20412 : nikomatsakis/rust/assoc-types, r=aturon
These changes fix various problems encountered getting japaric's `at-iter` branch to work. This branch converts the `Iterator` trait to use an associated type.
This commit is contained in:
@@ -1229,7 +1229,7 @@ fn walk_by_ref_captures(&mut self,
|
||||
// inferred by regionbk
|
||||
let upvar_id = ty::UpvarId { var_id: id_var,
|
||||
closure_expr_id: closure_expr.id };
|
||||
let upvar_borrow = self.typer.upvar_borrow(upvar_id);
|
||||
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();
|
||||
|
||||
self.delegate.borrow(closure_expr.id,
|
||||
closure_expr.span,
|
||||
|
||||
@@ -111,7 +111,9 @@
|
||||
|
||||
use middle::def::*;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::{pat_util, ty};
|
||||
use middle::pat_util;
|
||||
use middle::ty;
|
||||
use middle::ty::UnboxedClosureTyper;
|
||||
use lint;
|
||||
use util::nodemap::NodeMap;
|
||||
|
||||
@@ -1515,16 +1517,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
|
||||
fn fn_ret(&self, id: NodeId) -> ty::FnOutput<'tcx> {
|
||||
let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
|
||||
match fn_ty.sty {
|
||||
ty::ty_unboxed_closure(closure_def_id, _, _) =>
|
||||
self.ir.tcx.unboxed_closures()
|
||||
.borrow()
|
||||
.get(&closure_def_id)
|
||||
.unwrap()
|
||||
.closure_type
|
||||
.sig
|
||||
.0
|
||||
.output,
|
||||
_ => ty::ty_fn_ret(fn_ty)
|
||||
ty::ty_unboxed_closure(closure_def_id, _, substs) =>
|
||||
self.ir.tcx.unboxed_closure_type(closure_def_id, substs).sig.0.output,
|
||||
_ =>
|
||||
ty::ty_fn_ret(fn_ty),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
use middle::def;
|
||||
use middle::region;
|
||||
use middle::ty::{mod, Ty};
|
||||
use util::nodemap::{DefIdMap, NodeMap};
|
||||
use util::nodemap::{NodeMap};
|
||||
use util::ppaux::{ty_to_string, Repr};
|
||||
|
||||
use syntax::ast::{MutImmutable, MutMutable};
|
||||
@@ -280,7 +280,7 @@ impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
|
||||
/// In the borrow checker, in contrast, type checking is complete and we
|
||||
/// know that no errors have occurred, so we simply consult the tcx and we
|
||||
/// can be sure that only `Ok` results will occur.
|
||||
pub trait Typer<'tcx> {
|
||||
pub trait Typer<'tcx> : ty::UnboxedClosureTyper<'tcx> {
|
||||
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
|
||||
fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx>;
|
||||
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx>;
|
||||
@@ -290,11 +290,9 @@ fn node_method_origin(&self, method_call: ty::MethodCall)
|
||||
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
|
||||
fn is_method_call(&self, id: ast::NodeId) -> bool;
|
||||
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow>;
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
-> ast::CaptureClause;
|
||||
fn unboxed_closures<'a>(&'a self)
|
||||
-> &'a RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>>;
|
||||
}
|
||||
|
||||
impl MutabilityCategory {
|
||||
@@ -622,8 +620,7 @@ pub fn cat_def(&self,
|
||||
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, false)
|
||||
}
|
||||
ty::ty_unboxed_closure(closure_id, _, _) => {
|
||||
let unboxed_closures = self.typer.unboxed_closures().borrow();
|
||||
let kind = (*unboxed_closures)[closure_id].kind;
|
||||
let kind = self.typer.unboxed_closure_kind(closure_id);
|
||||
let mode = self.typer.capture_mode(fn_node_id);
|
||||
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, true)
|
||||
}
|
||||
@@ -800,7 +797,7 @@ fn cat_upvar(&self,
|
||||
}
|
||||
|
||||
// Look up upvar borrow so we can get its region
|
||||
let upvar_borrow = self.typer.upvar_borrow(upvar_id);
|
||||
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();
|
||||
let ptr = BorrowedPtr(upvar_borrow.kind, upvar_borrow.region);
|
||||
|
||||
Rc::new(cmt_ {
|
||||
|
||||
@@ -110,7 +110,7 @@ pub fn new() -> FulfillmentContext<'tcx> {
|
||||
pub fn normalize_projection_type<'a>(&mut self,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
||||
typer: &Typer<'tcx>,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>,
|
||||
projection_ty: ty::ProjectionTy<'tcx>,
|
||||
cause: ObligationCause<'tcx>)
|
||||
-> Ty<'tcx>
|
||||
@@ -187,7 +187,7 @@ pub fn region_obligations(&self,
|
||||
pub fn select_all_or_error<'a>(&mut self,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
||||
typer: &Typer<'tcx>)
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>)
|
||||
-> Result<(),Vec<FulfillmentError<'tcx>>>
|
||||
{
|
||||
try!(self.select_where_possible(infcx, param_env, typer));
|
||||
@@ -213,7 +213,7 @@ pub fn select_all_or_error<'a>(&mut self,
|
||||
pub fn select_new_obligations<'a>(&mut self,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
||||
typer: &Typer<'tcx>)
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>)
|
||||
-> Result<(),Vec<FulfillmentError<'tcx>>>
|
||||
{
|
||||
let mut selcx = SelectionContext::new(infcx, param_env, typer);
|
||||
@@ -223,7 +223,7 @@ pub fn select_new_obligations<'a>(&mut self,
|
||||
pub fn select_where_possible<'a>(&mut self,
|
||||
infcx: &InferCtxt<'a,'tcx>,
|
||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
||||
typer: &Typer<'tcx>)
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>)
|
||||
-> Result<(),Vec<FulfillmentError<'tcx>>>
|
||||
{
|
||||
let mut selcx = SelectionContext::new(infcx, param_env, typer);
|
||||
|
||||
@@ -102,7 +102,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>(
|
||||
|
||||
/// Compute result of projecting an associated type and unify it with
|
||||
/// `obligation.predicate.ty` (if we can).
|
||||
pub fn project_and_unify_type<'cx,'tcx>(
|
||||
fn project_and_unify_type<'cx,'tcx>(
|
||||
selcx: &mut SelectionContext<'cx,'tcx>,
|
||||
obligation: &ProjectionObligation<'tcx>)
|
||||
-> Result<Option<Vec<PredicateObligation<'tcx>>>, MismatchedProjectionTypes<'tcx>>
|
||||
@@ -135,9 +135,19 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
value: &T)
|
||||
-> Normalized<'tcx, T>
|
||||
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone
|
||||
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
|
||||
{
|
||||
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, 0);
|
||||
normalize_with_depth(selcx, cause, 0, value)
|
||||
}
|
||||
|
||||
pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
|
||||
cause: ObligationCause<'tcx>,
|
||||
depth: uint,
|
||||
value: &T)
|
||||
-> Normalized<'tcx, T>
|
||||
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
|
||||
{
|
||||
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth);
|
||||
let result = normalizer.fold(value);
|
||||
Normalized {
|
||||
value: result,
|
||||
@@ -278,9 +288,10 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
|
||||
// an impl, where-clause etc) and hence we must
|
||||
// re-normalize it
|
||||
|
||||
debug!("normalize_projection_type: projected_ty={} depth={}",
|
||||
debug!("normalize_projection_type: projected_ty={} depth={} obligations={}",
|
||||
projected_ty.repr(selcx.tcx()),
|
||||
depth);
|
||||
depth,
|
||||
obligations.repr(selcx.tcx()));
|
||||
|
||||
if ty::type_has_projection(projected_ty) {
|
||||
let tcx = selcx.tcx();
|
||||
@@ -644,3 +655,20 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
|
||||
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Normalized<'tcx, T> {
|
||||
Normalized {
|
||||
value: self.value.fold_with(folder),
|
||||
obligations: self.obligations.fold_with(folder),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Normalized<'tcx, T> {
|
||||
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
|
||||
format!("Normalized({},{})",
|
||||
self.value.repr(tcx),
|
||||
self.obligations.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use self::EvaluationResult::*;
|
||||
|
||||
use super::{DerivedObligationCause};
|
||||
use super::{project};
|
||||
use super::{PredicateObligation, Obligation, TraitObligation, ObligationCause};
|
||||
use super::{ObligationCauseCode, BuiltinDerivedObligation};
|
||||
use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
|
||||
@@ -29,7 +30,7 @@
|
||||
|
||||
use middle::fast_reject;
|
||||
use middle::mem_categorization::Typer;
|
||||
use middle::subst::{Subst, Substs, VecPerParamSpace};
|
||||
use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
|
||||
use middle::ty::{mod, AsPredicate, RegionEscape, ToPolyTraitRef, Ty};
|
||||
use middle::infer;
|
||||
use middle::infer::{InferCtxt, TypeFreshener};
|
||||
@@ -44,7 +45,7 @@
|
||||
pub struct SelectionContext<'cx, 'tcx:'cx> {
|
||||
infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
param_env: &'cx ty::ParameterEnvironment<'tcx>,
|
||||
typer: &'cx (Typer<'tcx>+'cx),
|
||||
closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+'cx),
|
||||
|
||||
/// Freshener used specifically for skolemizing entries on the
|
||||
/// obligation stack. This ensures that all entries on the stack
|
||||
@@ -177,12 +178,12 @@ enum EvaluationResult<'tcx> {
|
||||
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
param_env: &'cx ty::ParameterEnvironment<'tcx>,
|
||||
typer: &'cx Typer<'tcx>)
|
||||
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
|
||||
-> SelectionContext<'cx, 'tcx> {
|
||||
SelectionContext {
|
||||
infcx: infcx,
|
||||
param_env: param_env,
|
||||
typer: typer,
|
||||
closure_typer: closure_typer,
|
||||
freshener: infcx.freshener(),
|
||||
intercrate: false,
|
||||
}
|
||||
@@ -190,12 +191,12 @@ pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
|
||||
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
|
||||
param_env: &'cx ty::ParameterEnvironment<'tcx>,
|
||||
typer: &'cx Typer<'tcx>)
|
||||
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
|
||||
-> SelectionContext<'cx, 'tcx> {
|
||||
SelectionContext {
|
||||
infcx: infcx,
|
||||
param_env: param_env,
|
||||
typer: typer,
|
||||
closure_typer: closure_typer,
|
||||
freshener: infcx.freshener(),
|
||||
intercrate: true,
|
||||
}
|
||||
@@ -918,15 +919,7 @@ fn assemble_unboxed_closure_candidates(&mut self,
|
||||
kind,
|
||||
obligation.repr(self.tcx()));
|
||||
|
||||
let closure_kind = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
|
||||
Some(closure) => closure.kind,
|
||||
None => {
|
||||
self.tcx().sess.span_bug(
|
||||
obligation.cause.span,
|
||||
format!("No entry for unboxed closure: {}",
|
||||
closure_def_id.repr(self.tcx()))[]);
|
||||
}
|
||||
};
|
||||
let closure_kind = self.closure_typer.unboxed_closure_kind(closure_def_id);
|
||||
|
||||
debug!("closure_kind = {}", closure_kind);
|
||||
|
||||
@@ -1398,32 +1391,21 @@ fn builtin_bound(&mut self,
|
||||
return Ok(ParameterBuiltin);
|
||||
}
|
||||
|
||||
match self.tcx().freevars.borrow().get(&def_id.node) {
|
||||
None => {
|
||||
// No upvars.
|
||||
Ok(If(Vec::new()))
|
||||
match self.closure_typer.unboxed_closure_upvars(def_id, substs) {
|
||||
Some(upvars) => {
|
||||
Ok(If(upvars.iter().map(|c| c.ty).collect()))
|
||||
}
|
||||
|
||||
Some(freevars) => {
|
||||
let tys: Vec<Ty> =
|
||||
freevars
|
||||
.iter()
|
||||
.map(|freevar| {
|
||||
let freevar_def_id = freevar.def.def_id();
|
||||
self.typer.node_ty(freevar_def_id.node).subst(self.tcx(), substs)
|
||||
})
|
||||
.collect();
|
||||
Ok(If(tys))
|
||||
None => {
|
||||
Ok(AmbiguousBuiltin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::ty_struct(def_id, substs) => {
|
||||
let types: Vec<Ty> =
|
||||
ty::struct_fields(self.tcx(), def_id, substs)
|
||||
.iter()
|
||||
.map(|f| f.mt.ty)
|
||||
.collect();
|
||||
ty::struct_fields(self.tcx(), def_id, substs).iter()
|
||||
.map(|f| f.mt.ty)
|
||||
.collect();
|
||||
nominal(self, bound, def_id, types)
|
||||
}
|
||||
|
||||
@@ -1798,27 +1780,22 @@ fn confirm_unboxed_closure_candidate(&mut self,
|
||||
closure_def_id.repr(self.tcx()),
|
||||
substs.repr(self.tcx()));
|
||||
|
||||
let closure_type = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
|
||||
Some(closure) => closure.closure_type.clone(),
|
||||
None => {
|
||||
self.tcx().sess.span_bug(
|
||||
obligation.cause.span,
|
||||
format!("No entry for unboxed closure: {}",
|
||||
closure_def_id.repr(self.tcx()))[]);
|
||||
}
|
||||
};
|
||||
let closure_type = self.closure_typer.unboxed_closure_type(closure_def_id, substs);
|
||||
|
||||
debug!("confirm_unboxed_closure_candidate: closure_def_id={} closure_type={}",
|
||||
closure_def_id.repr(self.tcx()),
|
||||
closure_type.repr(self.tcx()));
|
||||
|
||||
let closure_sig = &closure_type.sig;
|
||||
let arguments_tuple = closure_sig.0.inputs[0];
|
||||
let substs =
|
||||
let trait_substs =
|
||||
Substs::new_trait(
|
||||
vec![arguments_tuple.subst(self.tcx(), substs),
|
||||
closure_sig.0.output.unwrap().subst(self.tcx(), substs)],
|
||||
vec![arguments_tuple, closure_sig.0.output.unwrap()],
|
||||
vec![],
|
||||
obligation.self_ty());
|
||||
let trait_ref = ty::Binder(Rc::new(ty::TraitRef {
|
||||
def_id: obligation.predicate.def_id(),
|
||||
substs: self.tcx().mk_substs(substs),
|
||||
substs: self.tcx().mk_substs(trait_substs),
|
||||
}));
|
||||
|
||||
debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",
|
||||
@@ -2100,7 +2077,7 @@ fn all_impls(&self, trait_def_id: ast::DefId) -> Vec<ast::DefId> {
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_predicates(&self,
|
||||
fn impl_predicates(&mut self,
|
||||
cause: ObligationCause<'tcx>,
|
||||
recursion_depth: uint,
|
||||
impl_def_id: ast::DefId,
|
||||
@@ -2111,8 +2088,19 @@ fn impl_predicates(&self,
|
||||
{
|
||||
let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
|
||||
let bounds = impl_generics.to_bounds(self.tcx(), impl_substs);
|
||||
let bounds = self.infcx().plug_leaks(skol_map, snapshot, &bounds);
|
||||
util::predicates_for_generics(self.tcx(), cause, recursion_depth, &bounds)
|
||||
let normalized_bounds =
|
||||
project::normalize_with_depth(self, cause.clone(), recursion_depth, &bounds);
|
||||
let normalized_bounds =
|
||||
self.infcx().plug_leaks(skol_map, snapshot, &normalized_bounds);
|
||||
let mut impl_obligations =
|
||||
util::predicates_for_generics(self.tcx(),
|
||||
cause,
|
||||
recursion_depth,
|
||||
&normalized_bounds.value);
|
||||
for obligation in normalized_bounds.obligations.into_iter() {
|
||||
impl_obligations.push(TypeSpace, obligation);
|
||||
}
|
||||
impl_obligations
|
||||
}
|
||||
|
||||
fn fn_family_trait_kind(&self,
|
||||
|
||||
+137
-32
@@ -2267,6 +2267,23 @@ pub fn trait_did(&self, cx: &ctxt) -> ast::DefId {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait UnboxedClosureTyper<'tcx> {
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind;
|
||||
|
||||
fn unboxed_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.
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>;
|
||||
}
|
||||
|
||||
impl<'tcx> CommonTypes<'tcx> {
|
||||
fn new(arena: &'tcx TypedArena<TyS<'tcx>>,
|
||||
interner: &mut FnvHashMap<InternedTy<'tcx>, Ty<'tcx>>)
|
||||
@@ -3353,7 +3370,7 @@ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
|
||||
ty_unboxed_closure(did, r, substs) => {
|
||||
// FIXME(#14449): `borrowed_contents` below assumes `&mut`
|
||||
// unboxed closure.
|
||||
let upvars = unboxed_closure_upvars(cx, did, substs);
|
||||
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
|
||||
TypeContents::union(upvars.as_slice(),
|
||||
|f| tc_ty(cx, f.ty, cache))
|
||||
| borrowed_contents(*r, MutMutable)
|
||||
@@ -3633,7 +3650,7 @@ fn subtypes_require<'tcx>(cx: &ctxt<'tcx>, seen: &mut Vec<DefId>,
|
||||
}
|
||||
|
||||
ty_unboxed_closure(did, _, substs) => {
|
||||
let upvars = unboxed_closure_upvars(cx, did, substs);
|
||||
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
|
||||
upvars.iter().any(|f| type_requires(cx, seen, r_ty, f.ty))
|
||||
}
|
||||
|
||||
@@ -3725,7 +3742,7 @@ fn are_inner_types_recursive<'tcx>(cx: &ctxt<'tcx>, sp: Span,
|
||||
find_nonrepresentable(cx, sp, seen, iter)
|
||||
}
|
||||
ty_unboxed_closure(did, _, substs) => {
|
||||
let upvars = unboxed_closure_upvars(cx, did, substs);
|
||||
let upvars = unboxed_closure_upvars(cx, did, substs).unwrap();
|
||||
find_nonrepresentable(cx, sp, seen, upvars.iter().map(|f| f.ty))
|
||||
}
|
||||
_ => Representable,
|
||||
@@ -5656,7 +5673,7 @@ pub fn tup_fields<'tcx>(v: &[Ty<'tcx>]) -> Vec<field<'tcx>> {
|
||||
}).collect()
|
||||
}
|
||||
|
||||
#[deriving(Copy)]
|
||||
#[deriving(Copy, Clone)]
|
||||
pub struct UnboxedClosureUpvar<'tcx> {
|
||||
pub def: def::Def,
|
||||
pub span: Span,
|
||||
@@ -5664,38 +5681,67 @@ pub struct UnboxedClosureUpvar<'tcx> {
|
||||
}
|
||||
|
||||
// Returns a list of `UnboxedClosureUpvar`s for each upvar.
|
||||
pub fn unboxed_closure_upvars<'tcx>(tcx: &ctxt<'tcx>, closure_id: ast::DefId, substs: &Substs<'tcx>)
|
||||
-> Vec<UnboxedClosureUpvar<'tcx>> {
|
||||
pub fn unboxed_closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
|
||||
closure_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>
|
||||
{
|
||||
// Presently an unboxed closure type cannot "escape" out of a
|
||||
// function, so we will only encounter ones that originated in the
|
||||
// local crate or were inlined into it along with some function.
|
||||
// This may change if abstract return types of some sort are
|
||||
// implemented.
|
||||
assert!(closure_id.krate == ast::LOCAL_CRATE);
|
||||
let tcx = typer.tcx();
|
||||
let capture_mode = tcx.capture_modes.borrow()[closure_id.node].clone();
|
||||
match tcx.freevars.borrow().get(&closure_id.node) {
|
||||
None => vec![],
|
||||
None => Some(vec![]),
|
||||
Some(ref freevars) => {
|
||||
freevars.iter().map(|freevar| {
|
||||
let freevar_def_id = freevar.def.def_id();
|
||||
let freevar_ty = node_id_to_type(tcx, freevar_def_id.node);
|
||||
let mut freevar_ty = freevar_ty.subst(tcx, substs);
|
||||
if capture_mode == ast::CaptureByRef {
|
||||
let borrow = tcx.upvar_borrow_map.borrow()[ty::UpvarId {
|
||||
var_id: freevar_def_id.node,
|
||||
closure_expr_id: closure_id.node
|
||||
}].clone();
|
||||
freevar_ty = mk_rptr(tcx, tcx.mk_region(borrow.region), ty::mt {
|
||||
ty: freevar_ty,
|
||||
mutbl: borrow.kind.to_mutbl_lossy()
|
||||
});
|
||||
}
|
||||
UnboxedClosureUpvar {
|
||||
def: freevar.def,
|
||||
span: freevar.span,
|
||||
ty: freevar_ty
|
||||
}
|
||||
}).collect()
|
||||
freevars.iter()
|
||||
.map(|freevar| {
|
||||
let freevar_def_id = freevar.def.def_id();
|
||||
let freevar_ty = typer.node_ty(freevar_def_id.node);
|
||||
let freevar_ty = freevar_ty.subst(tcx, substs);
|
||||
|
||||
match capture_mode {
|
||||
ast::CaptureByValue => {
|
||||
Some(UnboxedClosureUpvar { def: freevar.def,
|
||||
span: freevar.span,
|
||||
ty: freevar_ty })
|
||||
}
|
||||
|
||||
ast::CaptureByRef => {
|
||||
let upvar_id = ty::UpvarId {
|
||||
var_id: freevar_def_id.node,
|
||||
closure_expr_id: closure_id.node
|
||||
};
|
||||
|
||||
// FIXME
|
||||
let freevar_ref_ty = match typer.upvar_borrow(upvar_id) {
|
||||
Some(borrow) => {
|
||||
mk_rptr(tcx,
|
||||
tcx.mk_region(borrow.region),
|
||||
ty::mt {
|
||||
ty: freevar_ty,
|
||||
mutbl: borrow.kind.to_mutbl_lossy(),
|
||||
})
|
||||
}
|
||||
None => {
|
||||
// FIXME(#16640) we should really return None here;
|
||||
// but that requires better inference integration,
|
||||
// for now gin up something.
|
||||
freevar_ty
|
||||
}
|
||||
};
|
||||
Some(UnboxedClosureUpvar {
|
||||
def: freevar.def,
|
||||
span: freevar.span,
|
||||
ty: freevar_ref_ty,
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6509,21 +6555,42 @@ fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>
|
||||
self.region_maps.temporary_scope(rvalue_id)
|
||||
}
|
||||
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
|
||||
self.upvar_borrow_map.borrow()[upvar_id].clone()
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
|
||||
Some(self.upvar_borrow_map.borrow()[upvar_id].clone())
|
||||
}
|
||||
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
-> ast::CaptureClause {
|
||||
self.capture_modes.borrow()[closure_expr_id].clone()
|
||||
}
|
||||
}
|
||||
|
||||
fn unboxed_closures<'a>(&'a self)
|
||||
-> &'a RefCell<DefIdMap<UnboxedClosure<'tcx>>> {
|
||||
&self.unboxed_closures
|
||||
impl<'tcx> UnboxedClosureTyper<'tcx> for ty::ctxt<'tcx> {
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
self.unboxed_closures.borrow()[def_id].kind
|
||||
}
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
self.unboxed_closures.borrow()[def_id].closure_type.subst(self, substs)
|
||||
}
|
||||
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<UnboxedClosureUpvar<'tcx>>>
|
||||
{
|
||||
unboxed_closure_upvars(self, def_id, substs)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// The category of explicit self.
|
||||
#[deriving(Clone, Copy, Eq, PartialEq, Show)]
|
||||
pub enum ExplicitSelfCategory {
|
||||
@@ -7040,12 +7107,30 @@ pub trait HasProjectionTypes {
|
||||
fn has_projection_types(&self) -> bool;
|
||||
}
|
||||
|
||||
impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for Vec<T> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.iter().any(|p| p.has_projection_types())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx,T:HasProjectionTypes> HasProjectionTypes for VecPerParamSpace<T> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.iter().any(|p| p.has_projection_types())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasProjectionTypes for ClosureTy<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.sig.has_projection_types()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasProjectionTypes for UnboxedClosureUpvar<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.ty.has_projection_types()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> HasProjectionTypes for ty::GenericBounds<'tcx> {
|
||||
fn has_projection_types(&self) -> bool {
|
||||
self.predicates.has_projection_types()
|
||||
@@ -7245,3 +7330,23 @@ fn references_error(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Repr<'tcx> for ClosureTy<'tcx> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
format!("ClosureTy({},{},{},{},{},{})",
|
||||
self.unsafety,
|
||||
self.onceness,
|
||||
self.store,
|
||||
self.bounds.repr(tcx),
|
||||
self.sig.repr(tcx),
|
||||
self.abi)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Repr<'tcx> for UnboxedClosureUpvar<'tcx> {
|
||||
fn repr(&self, tcx: &ctxt<'tcx>) -> String {
|
||||
format!("UnboxedClosureUpvar({},{})",
|
||||
self.def.repr(tcx),
|
||||
self.ty.repr(tcx))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -532,6 +532,16 @@ fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::OutlivesPredicate
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::UnboxedClosureUpvar<'tcx> {
|
||||
fn fold_with<F:TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::UnboxedClosureUpvar<'tcx> {
|
||||
ty::UnboxedClosureUpvar {
|
||||
def: self.def,
|
||||
span: self.span,
|
||||
ty: self.ty.fold_with(folder),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// "super" routines: these are the default implementations for TypeFolder.
|
||||
//
|
||||
|
||||
@@ -168,7 +168,7 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
Univariant(mk_struct(cx, ftys[], packed, t), dtor)
|
||||
}
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs);
|
||||
let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs).unwrap();
|
||||
let upvar_types = upvars.iter().map(|u| u.ty).collect::<Vec<_>>();
|
||||
Univariant(mk_struct(cx, upvar_types[], false, t), false)
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
use middle::subst;
|
||||
use middle::weak_lang_items;
|
||||
use middle::subst::{Subst, Substs};
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::ty::{mod, Ty, UnboxedClosureTyper};
|
||||
use session::config::{mod, NoDebugInfo, FullDebugInfo};
|
||||
use session::Session;
|
||||
use trans::_match;
|
||||
@@ -257,12 +257,12 @@ fn get_extern_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
pub fn self_type_for_unboxed_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
closure_id: ast::DefId,
|
||||
fn_ty: Ty<'tcx>)
|
||||
-> Ty<'tcx> {
|
||||
let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
|
||||
let unboxed_closure = &(*unboxed_closures)[closure_id];
|
||||
match unboxed_closure.kind {
|
||||
closure_id: ast::DefId,
|
||||
fn_ty: Ty<'tcx>)
|
||||
-> Ty<'tcx>
|
||||
{
|
||||
let unboxed_closure_kind = ccx.tcx().unboxed_closure_kind(closure_id);
|
||||
match unboxed_closure_kind {
|
||||
ty::FnUnboxedClosureKind => {
|
||||
ty::mk_imm_rptr(ccx.tcx(), ccx.tcx().mk_region(ty::ReStatic), fn_ty)
|
||||
}
|
||||
@@ -291,13 +291,15 @@ pub fn decl_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
(f.sig.0.inputs.clone(), f.sig.0.output, f.abi, Some(Type::i8p(ccx)))
|
||||
}
|
||||
ty::ty_unboxed_closure(closure_did, _, substs) => {
|
||||
let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
|
||||
let unboxed_closure = &(*unboxed_closures)[closure_did];
|
||||
let function_type = unboxed_closure.closure_type.clone();
|
||||
let typer = common::NormalizingUnboxedClosureTyper::new(ccx.tcx());
|
||||
let function_type = typer.unboxed_closure_type(closure_did, substs);
|
||||
let self_type = self_type_for_unboxed_closure(ccx, closure_did, fn_ty);
|
||||
let llenvironment_type = type_of_explicit_arg(ccx, self_type);
|
||||
(function_type.sig.0.inputs.iter().map(|t| t.subst(ccx.tcx(), substs)).collect(),
|
||||
function_type.sig.0.output.subst(ccx.tcx(), substs),
|
||||
debug!("decl_rust_fn: function_type={} self_type={}",
|
||||
function_type.repr(ccx.tcx()),
|
||||
self_type.repr(ccx.tcx()));
|
||||
(function_type.sig.0.inputs,
|
||||
function_type.sig.0.output,
|
||||
RustCall,
|
||||
Some(llenvironment_type))
|
||||
}
|
||||
@@ -729,7 +731,7 @@ fn iter_variant<'a, 'blk, 'tcx>(cx: Block<'blk, 'tcx>,
|
||||
}
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
let repr = adt::represent_type(cx.ccx(), t);
|
||||
let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs);
|
||||
let upvars = ty::unboxed_closure_upvars(cx.tcx(), def_id, substs).unwrap();
|
||||
for (i, upvar) in upvars.iter().enumerate() {
|
||||
let llupvar = adt::trans_field_ptr(cx, &*repr, data_ptr, 0, i);
|
||||
cx = f(cx, llupvar, upvar.ty);
|
||||
@@ -2436,11 +2438,9 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
|
||||
ty::ty_closure(ref f) => (f.sig.clone(), f.abi, true),
|
||||
ty::ty_bare_fn(_, ref f) => (f.sig.clone(), f.abi, false),
|
||||
ty::ty_unboxed_closure(closure_did, _, substs) => {
|
||||
let unboxed_closures = ccx.tcx().unboxed_closures.borrow();
|
||||
let ref function_type = (*unboxed_closures)[closure_did]
|
||||
.closure_type;
|
||||
|
||||
(function_type.sig.subst(ccx.tcx(), substs), RustCall, true)
|
||||
let typer = common::NormalizingUnboxedClosureTyper::new(ccx.tcx());
|
||||
let function_type = typer.unboxed_closure_type(closure_did, substs);
|
||||
(function_type.sig, RustCall, true)
|
||||
}
|
||||
_ => ccx.sess().bug("expected closure or function.")
|
||||
};
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
use trans::datum::{Datum, DatumBlock, Expr, Lvalue, rvalue_scratch_datum};
|
||||
use trans::debuginfo;
|
||||
use trans::expr;
|
||||
use trans::monomorphize::MonoId;
|
||||
use trans::monomorphize::{mod, MonoId};
|
||||
use trans::type_of::*;
|
||||
use trans::type_::Type;
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::subst::{Subst, Substs};
|
||||
use middle::ty::{mod, Ty, UnboxedClosureTyper};
|
||||
use middle::subst::{Substs};
|
||||
use session::config::FullDebugInfo;
|
||||
use util::ppaux::Repr;
|
||||
use util::ppaux::ty_to_string;
|
||||
@@ -464,7 +464,7 @@ pub fn get_or_create_declaration_if_unboxed_closure<'blk, 'tcx>(bcx: Block<'blk,
|
||||
}
|
||||
|
||||
let function_type = ty::node_id_to_type(bcx.tcx(), closure_id.node);
|
||||
let function_type = function_type.subst(bcx.tcx(), substs);
|
||||
let function_type = monomorphize::apply_param_substs(bcx.tcx(), substs, &function_type);
|
||||
|
||||
// Normalize type so differences in regions and typedefs don't cause
|
||||
// duplicate declarations
|
||||
@@ -511,7 +511,8 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
|
||||
body: &ast::Block,
|
||||
id: ast::NodeId,
|
||||
dest: expr::Dest)
|
||||
-> Block<'blk, 'tcx> {
|
||||
-> Block<'blk, 'tcx>
|
||||
{
|
||||
let _icx = push_ctxt("closure::trans_unboxed_closure");
|
||||
|
||||
debug!("trans_unboxed_closure()");
|
||||
@@ -522,9 +523,13 @@ pub fn trans_unboxed_closure<'blk, 'tcx>(
|
||||
closure_id,
|
||||
bcx.fcx.param_substs).unwrap();
|
||||
|
||||
let function_type = (*bcx.tcx().unboxed_closures.borrow())[closure_id]
|
||||
.closure_type
|
||||
.clone();
|
||||
// Get the type of this closure. Use the current `param_substs` as
|
||||
// the closure substitutions. This makes sense because the closure
|
||||
// takes the same set of type arguments as the enclosing fn, and
|
||||
// this function (`trans_unboxed_closure`) is invoked at the point
|
||||
// of the closure expression.
|
||||
let typer = NormalizingUnboxedClosureTyper::new(bcx.tcx());
|
||||
let function_type = typer.unboxed_closure_type(closure_id, bcx.fcx.param_substs);
|
||||
let function_type = ty::mk_closure(bcx.tcx(), function_type);
|
||||
|
||||
let freevars: Vec<ty::Freevar> =
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
use middle::ty_fold;
|
||||
use middle::ty_fold::{TypeFolder, TypeFoldable};
|
||||
use util::ppaux::Repr;
|
||||
use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
|
||||
use util::nodemap::{FnvHashMap, NodeMap};
|
||||
|
||||
use arena::TypedArena;
|
||||
use libc::{c_uint, c_char};
|
||||
@@ -617,13 +617,8 @@ fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>
|
||||
self.tcx().region_maps.temporary_scope(rvalue_id)
|
||||
}
|
||||
|
||||
fn unboxed_closures<'a>(&'a self)
|
||||
-> &'a RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>> {
|
||||
&self.tcx().unboxed_closures
|
||||
}
|
||||
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
|
||||
self.tcx().upvar_borrow_map.borrow()[upvar_id].clone()
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
|
||||
Some(self.tcx().upvar_borrow_map.borrow()[upvar_id].clone())
|
||||
}
|
||||
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
@@ -632,6 +627,34 @@ fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'blk, 'tcx> ty::UnboxedClosureTyper<'tcx> for BlockS<'blk, 'tcx> {
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
|
||||
typer.unboxed_closure_kind(def_id)
|
||||
}
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
|
||||
typer.unboxed_closure_type(def_id, substs)
|
||||
}
|
||||
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
|
||||
{
|
||||
let typer = NormalizingUnboxedClosureTyper::new(self.tcx());
|
||||
typer.unboxed_closure_upvars(def_id, substs)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Result<'blk, 'tcx: 'blk> {
|
||||
pub bcx: Block<'blk, 'tcx>,
|
||||
pub val: ValueRef
|
||||
@@ -924,7 +947,8 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
|
||||
// Do the initial selection for the obligation. This yields the
|
||||
// shallow result we are looking for -- that is, what specific impl.
|
||||
let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env, tcx);
|
||||
let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx);
|
||||
let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env, &typer);
|
||||
let obligation = traits::Obligation::new(traits::ObligationCause::dummy(),
|
||||
trait_ref.to_poly_trait_predicate());
|
||||
let selection = match selcx.select(&obligation) {
|
||||
@@ -968,6 +992,47 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||
vtable
|
||||
}
|
||||
|
||||
pub struct NormalizingUnboxedClosureTyper<'a,'tcx:'a> {
|
||||
tcx: &'a ty::ctxt<'tcx>
|
||||
}
|
||||
|
||||
impl<'a,'tcx> NormalizingUnboxedClosureTyper<'a,'tcx> {
|
||||
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> NormalizingUnboxedClosureTyper<'a,'tcx> {
|
||||
NormalizingUnboxedClosureTyper { tcx: tcx }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,'tcx> ty::UnboxedClosureTyper<'tcx> for NormalizingUnboxedClosureTyper<'a,'tcx> {
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
self.tcx.unboxed_closure_kind(def_id)
|
||||
}
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
// the substitutions in `substs` are already monomorphized,
|
||||
// but we still must normalize associated types
|
||||
let closure_ty = self.tcx.unboxed_closure_type(def_id, substs);
|
||||
monomorphize::normalize_associated_type(self.tcx, &closure_ty)
|
||||
}
|
||||
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
|
||||
{
|
||||
// the substitutions in `substs` are already monomorphized,
|
||||
// but we still must normalize associated types
|
||||
let result = ty::unboxed_closure_upvars(self.tcx, def_id, substs);
|
||||
monomorphize::normalize_associated_type(self.tcx, &result)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
|
||||
infcx: &infer::InferCtxt<'a,'tcx>,
|
||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
||||
@@ -982,7 +1047,8 @@ pub fn drain_fulfillment_cx<'a,'tcx,T>(span: Span,
|
||||
// In principle, we only need to do this so long as `result`
|
||||
// contains unbound type parameters. It could be a slight
|
||||
// optimization to stop iterating early.
|
||||
match fulfill_cx.select_all_or_error(infcx, param_env, infcx.tcx) {
|
||||
let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx);
|
||||
match fulfill_cx.select_all_or_error(infcx, param_env, &typer) {
|
||||
Ok(()) => { }
|
||||
Err(errors) => {
|
||||
if errors.iter().all(|e| e.is_overflow()) {
|
||||
|
||||
@@ -194,13 +194,13 @@
|
||||
use llvm::{ModuleRef, ContextRef, ValueRef};
|
||||
use llvm::debuginfo::*;
|
||||
use metadata::csearch;
|
||||
use middle::subst::{mod, Subst, Substs};
|
||||
use middle::subst::{mod, Substs};
|
||||
use trans::{mod, adt, machine, type_of};
|
||||
use trans::common::*;
|
||||
use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef};
|
||||
use trans::monomorphize;
|
||||
use trans::type_::Type;
|
||||
use middle::ty::{mod, Ty};
|
||||
use middle::ty::{mod, Ty, UnboxedClosureTyper};
|
||||
use middle::pat_util;
|
||||
use session::config::{mod, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
|
||||
use util::nodemap::{DefIdMap, NodeMap, FnvHashMap, FnvHashSet};
|
||||
@@ -470,9 +470,9 @@ fn get_unique_type_id_of_type<'a>(&mut self, cx: &CrateContext<'a, 'tcx>,
|
||||
closure_ty.clone(),
|
||||
&mut unique_type_id);
|
||||
},
|
||||
ty::ty_unboxed_closure(ref def_id, _, substs) => {
|
||||
let closure_ty = cx.tcx().unboxed_closures.borrow()
|
||||
.get(def_id).unwrap().closure_type.subst(cx.tcx(), substs);
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
|
||||
let closure_ty = typer.unboxed_closure_type(def_id, substs);
|
||||
self.get_unique_type_id_of_closure_type(cx,
|
||||
closure_ty,
|
||||
&mut unique_type_id);
|
||||
@@ -3020,9 +3020,9 @@ fn type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
|
||||
ty::ty_closure(ref closurety) => {
|
||||
subroutine_type_metadata(cx, unique_type_id, &closurety.sig, usage_site_span)
|
||||
}
|
||||
ty::ty_unboxed_closure(ref def_id, _, substs) => {
|
||||
let sig = cx.tcx().unboxed_closures.borrow()
|
||||
.get(def_id).unwrap().closure_type.sig.subst(cx.tcx(), substs);
|
||||
ty::ty_unboxed_closure(def_id, _, substs) => {
|
||||
let typer = NormalizingUnboxedClosureTyper::new(cx.tcx());
|
||||
let sig = typer.unboxed_closure_type(def_id, substs).sig;
|
||||
subroutine_type_metadata(cx, unique_type_id, &sig, usage_site_span)
|
||||
}
|
||||
ty::ty_struct(def_id, substs) => {
|
||||
|
||||
@@ -323,7 +323,8 @@ pub fn normalize_associated_type<'tcx,T>(tcx: &ty::ctxt<'tcx>, value: &T) -> T
|
||||
|
||||
let infcx = infer::new_infer_ctxt(tcx);
|
||||
let param_env = ty::empty_parameter_environment();
|
||||
let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env, tcx);
|
||||
let typer = NormalizingUnboxedClosureTyper::new(infcx.tcx);
|
||||
let mut selcx = traits::SelectionContext::new(&infcx, ¶m_env, &typer);
|
||||
let cause = traits::ObligationCause::dummy();
|
||||
let traits::Normalized { value: result, obligations } =
|
||||
traits::normalize(&mut selcx, cause, value);
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
use middle::infer::InferCtxt;
|
||||
use middle::mem_categorization as mc;
|
||||
use middle::traits::{mod, FulfillmentContext, Normalized, MiscObligation,
|
||||
SelectionContext, ObligationCause};
|
||||
use middle::ty::{mod, HasProjectionTypes};
|
||||
@@ -20,7 +19,7 @@
|
||||
|
||||
pub fn normalize_associated_types_in<'a,'tcx,T>(infcx: &InferCtxt<'a,'tcx>,
|
||||
param_env: &ty::ParameterEnvironment<'tcx>,
|
||||
typer: &(mc::Typer<'tcx>+'a),
|
||||
typer: &(ty::UnboxedClosureTyper<'tcx>+'a),
|
||||
fulfillment_cx: &mut FulfillmentContext<'tcx>,
|
||||
span: Span,
|
||||
body_id: ast::NodeId,
|
||||
|
||||
@@ -319,15 +319,37 @@ fn is_method_call(&self, id: ast::NodeId) -> bool {
|
||||
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<CodeExtent> {
|
||||
self.tcx().temporary_scope(rvalue_id)
|
||||
}
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow {
|
||||
self.inh.upvar_borrow_map.borrow()[upvar_id].clone()
|
||||
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow> {
|
||||
self.inh.upvar_borrow_map.borrow().get(&upvar_id).cloned()
|
||||
}
|
||||
fn capture_mode(&self, closure_expr_id: ast::NodeId)
|
||||
-> ast::CaptureClause {
|
||||
self.ccx.tcx.capture_mode(closure_expr_id)
|
||||
}
|
||||
fn unboxed_closures(&self) -> &RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>> {
|
||||
&self.inh.unboxed_closures
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> ty::UnboxedClosureTyper<'tcx> for FnCtxt<'a, 'tcx> {
|
||||
fn unboxed_closure_kind(&self,
|
||||
def_id: ast::DefId)
|
||||
-> ty::UnboxedClosureKind
|
||||
{
|
||||
self.inh.unboxed_closures.borrow()[def_id].kind
|
||||
}
|
||||
|
||||
fn unboxed_closure_type(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &subst::Substs<'tcx>)
|
||||
-> ty::ClosureTy<'tcx>
|
||||
{
|
||||
self.inh.unboxed_closures.borrow()[def_id].closure_type.subst(self.tcx(), substs)
|
||||
}
|
||||
|
||||
fn unboxed_closure_upvars(&self,
|
||||
def_id: ast::DefId,
|
||||
substs: &Substs<'tcx>)
|
||||
-> Option<Vec<ty::UnboxedClosureUpvar<'tcx>>>
|
||||
{
|
||||
ty::unboxed_closure_upvars(self, def_id, substs)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +374,7 @@ fn new(tcx: &'a ty::ctxt<'tcx>,
|
||||
}
|
||||
|
||||
fn normalize_associated_types_in<T>(&self,
|
||||
typer: &mc::Typer<'tcx>,
|
||||
typer: &ty::UnboxedClosureTyper<'tcx>,
|
||||
span: Span,
|
||||
body_id: ast::NodeId,
|
||||
value: &T)
|
||||
|
||||
Reference in New Issue
Block a user