Skip to content

Commit 1f887c8

Browse files
committed
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.
2 parents ee3c595 + 345e38c commit 1f887c8

File tree

16 files changed

+381
-164
lines changed

16 files changed

+381
-164
lines changed

src/librustc/middle/expr_use_visitor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
12291229
// inferred by regionbk
12301230
let upvar_id = ty::UpvarId { var_id: id_var,
12311231
closure_expr_id: closure_expr.id };
1232-
let upvar_borrow = self.typer.upvar_borrow(upvar_id);
1232+
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();
12331233

12341234
self.delegate.borrow(closure_expr.id,
12351235
closure_expr.span,

src/librustc/middle/liveness.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ use self::VarKind::*;
111111

112112
use middle::def::*;
113113
use middle::mem_categorization::Typer;
114-
use middle::{pat_util, ty};
114+
use middle::pat_util;
115+
use middle::ty;
116+
use middle::ty::UnboxedClosureTyper;
115117
use lint;
116118
use util::nodemap::NodeMap;
117119

@@ -1515,16 +1517,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
15151517
fn fn_ret(&self, id: NodeId) -> ty::FnOutput<'tcx> {
15161518
let fn_ty = ty::node_id_to_type(self.ir.tcx, id);
15171519
match fn_ty.sty {
1518-
ty::ty_unboxed_closure(closure_def_id, _, _) =>
1519-
self.ir.tcx.unboxed_closures()
1520-
.borrow()
1521-
.get(&closure_def_id)
1522-
.unwrap()
1523-
.closure_type
1524-
.sig
1525-
.0
1526-
.output,
1527-
_ => ty::ty_fn_ret(fn_ty)
1520+
ty::ty_unboxed_closure(closure_def_id, _, substs) =>
1521+
self.ir.tcx.unboxed_closure_type(closure_def_id, substs).sig.0.output,
1522+
_ =>
1523+
ty::ty_fn_ret(fn_ty),
15281524
}
15291525
}
15301526

src/librustc/middle/mem_categorization.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ pub use self::categorization::*;
7474
use middle::def;
7575
use middle::region;
7676
use middle::ty::{mod, Ty};
77-
use util::nodemap::{DefIdMap, NodeMap};
77+
use util::nodemap::{NodeMap};
7878
use util::ppaux::{ty_to_string, Repr};
7979

8080
use syntax::ast::{MutImmutable, MutMutable};
@@ -280,7 +280,7 @@ impl<'t,TYPER:'t> Copy for MemCategorizationContext<'t,TYPER> {}
280280
/// In the borrow checker, in contrast, type checking is complete and we
281281
/// know that no errors have occurred, so we simply consult the tcx and we
282282
/// can be sure that only `Ok` results will occur.
283-
pub trait Typer<'tcx> {
283+
pub trait Typer<'tcx> : ty::UnboxedClosureTyper<'tcx> {
284284
fn tcx<'a>(&'a self) -> &'a ty::ctxt<'tcx>;
285285
fn node_ty(&self, id: ast::NodeId) -> Ty<'tcx>;
286286
fn expr_ty_adjusted(&self, expr: &ast::Expr) -> Ty<'tcx>;
@@ -290,11 +290,9 @@ pub trait Typer<'tcx> {
290290
fn adjustments<'a>(&'a self) -> &'a RefCell<NodeMap<ty::AutoAdjustment<'tcx>>>;
291291
fn is_method_call(&self, id: ast::NodeId) -> bool;
292292
fn temporary_scope(&self, rvalue_id: ast::NodeId) -> Option<region::CodeExtent>;
293-
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> ty::UpvarBorrow;
293+
fn upvar_borrow(&self, upvar_id: ty::UpvarId) -> Option<ty::UpvarBorrow>;
294294
fn capture_mode(&self, closure_expr_id: ast::NodeId)
295295
-> ast::CaptureClause;
296-
fn unboxed_closures<'a>(&'a self)
297-
-> &'a RefCell<DefIdMap<ty::UnboxedClosure<'tcx>>>;
298296
}
299297

300298
impl MutabilityCategory {
@@ -622,8 +620,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
622620
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, false)
623621
}
624622
ty::ty_unboxed_closure(closure_id, _, _) => {
625-
let unboxed_closures = self.typer.unboxed_closures().borrow();
626-
let kind = (*unboxed_closures)[closure_id].kind;
623+
let kind = self.typer.unboxed_closure_kind(closure_id);
627624
let mode = self.typer.capture_mode(fn_node_id);
628625
self.cat_upvar(id, span, var_id, fn_node_id, kind, mode, true)
629626
}
@@ -800,7 +797,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
800797
}
801798

802799
// Look up upvar borrow so we can get its region
803-
let upvar_borrow = self.typer.upvar_borrow(upvar_id);
800+
let upvar_borrow = self.typer.upvar_borrow(upvar_id).unwrap();
804801
let ptr = BorrowedPtr(upvar_borrow.kind, upvar_borrow.region);
805802

806803
Rc::new(cmt_ {

src/librustc/middle/traits/fulfill.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
110110
pub fn normalize_projection_type<'a>(&mut self,
111111
infcx: &InferCtxt<'a,'tcx>,
112112
param_env: &ty::ParameterEnvironment<'tcx>,
113-
typer: &Typer<'tcx>,
113+
typer: &ty::UnboxedClosureTyper<'tcx>,
114114
projection_ty: ty::ProjectionTy<'tcx>,
115115
cause: ObligationCause<'tcx>)
116116
-> Ty<'tcx>
@@ -187,7 +187,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
187187
pub fn select_all_or_error<'a>(&mut self,
188188
infcx: &InferCtxt<'a,'tcx>,
189189
param_env: &ty::ParameterEnvironment<'tcx>,
190-
typer: &Typer<'tcx>)
190+
typer: &ty::UnboxedClosureTyper<'tcx>)
191191
-> Result<(),Vec<FulfillmentError<'tcx>>>
192192
{
193193
try!(self.select_where_possible(infcx, param_env, typer));
@@ -213,7 +213,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
213213
pub fn select_new_obligations<'a>(&mut self,
214214
infcx: &InferCtxt<'a,'tcx>,
215215
param_env: &ty::ParameterEnvironment<'tcx>,
216-
typer: &Typer<'tcx>)
216+
typer: &ty::UnboxedClosureTyper<'tcx>)
217217
-> Result<(),Vec<FulfillmentError<'tcx>>>
218218
{
219219
let mut selcx = SelectionContext::new(infcx, param_env, typer);
@@ -223,7 +223,7 @@ impl<'tcx> FulfillmentContext<'tcx> {
223223
pub fn select_where_possible<'a>(&mut self,
224224
infcx: &InferCtxt<'a,'tcx>,
225225
param_env: &ty::ParameterEnvironment<'tcx>,
226-
typer: &Typer<'tcx>)
226+
typer: &ty::UnboxedClosureTyper<'tcx>)
227227
-> Result<(),Vec<FulfillmentError<'tcx>>>
228228
{
229229
let mut selcx = SelectionContext::new(infcx, param_env, typer);

src/librustc/middle/traits/project.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ pub fn poly_project_and_unify_type<'cx,'tcx>(
102102

103103
/// Compute result of projecting an associated type and unify it with
104104
/// `obligation.predicate.ty` (if we can).
105-
pub fn project_and_unify_type<'cx,'tcx>(
105+
fn project_and_unify_type<'cx,'tcx>(
106106
selcx: &mut SelectionContext<'cx,'tcx>,
107107
obligation: &ProjectionObligation<'tcx>)
108108
-> Result<Option<Vec<PredicateObligation<'tcx>>>, MismatchedProjectionTypes<'tcx>>
@@ -135,9 +135,19 @@ pub fn normalize<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
135135
cause: ObligationCause<'tcx>,
136136
value: &T)
137137
-> Normalized<'tcx, T>
138-
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone
138+
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
139139
{
140-
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, 0);
140+
normalize_with_depth(selcx, cause, 0, value)
141+
}
142+
143+
pub fn normalize_with_depth<'a,'b,'tcx,T>(selcx: &'a mut SelectionContext<'b,'tcx>,
144+
cause: ObligationCause<'tcx>,
145+
depth: uint,
146+
value: &T)
147+
-> Normalized<'tcx, T>
148+
where T : TypeFoldable<'tcx> + HasProjectionTypes + Clone + Repr<'tcx>
149+
{
150+
let mut normalizer = AssociatedTypeNormalizer::new(selcx, cause, depth);
141151
let result = normalizer.fold(value);
142152
Normalized {
143153
value: result,
@@ -278,9 +288,10 @@ fn opt_normalize_projection_type<'a,'b,'tcx>(
278288
// an impl, where-clause etc) and hence we must
279289
// re-normalize it
280290

281-
debug!("normalize_projection_type: projected_ty={} depth={}",
291+
debug!("normalize_projection_type: projected_ty={} depth={} obligations={}",
282292
projected_ty.repr(selcx.tcx()),
283-
depth);
293+
depth,
294+
obligations.repr(selcx.tcx()));
284295

285296
if ty::type_has_projection(projected_ty) {
286297
let tcx = selcx.tcx();
@@ -644,3 +655,20 @@ impl<'tcx> Repr<'tcx> for ProjectionTyCandidate<'tcx> {
644655
}
645656
}
646657
}
658+
659+
impl<'tcx, T: TypeFoldable<'tcx>> TypeFoldable<'tcx> for Normalized<'tcx, T> {
660+
fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> Normalized<'tcx, T> {
661+
Normalized {
662+
value: self.value.fold_with(folder),
663+
obligations: self.obligations.fold_with(folder),
664+
}
665+
}
666+
}
667+
668+
impl<'tcx, T:Repr<'tcx>> Repr<'tcx> for Normalized<'tcx, T> {
669+
fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
670+
format!("Normalized({},{})",
671+
self.value.repr(tcx),
672+
self.obligations.repr(tcx))
673+
}
674+
}

src/librustc/middle/traits/select.rs

Lines changed: 38 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use self::BuiltinBoundConditions::*;
1818
use self::EvaluationResult::*;
1919

2020
use super::{DerivedObligationCause};
21+
use super::{project};
2122
use super::{PredicateObligation, Obligation, TraitObligation, ObligationCause};
2223
use super::{ObligationCauseCode, BuiltinDerivedObligation};
2324
use super::{SelectionError, Unimplemented, Overflow, OutputTypeParameterMismatch};
@@ -29,7 +30,7 @@ use super::{util};
2930

3031
use middle::fast_reject;
3132
use middle::mem_categorization::Typer;
32-
use middle::subst::{Subst, Substs, VecPerParamSpace};
33+
use middle::subst::{Subst, Substs, TypeSpace, VecPerParamSpace};
3334
use middle::ty::{mod, AsPredicate, RegionEscape, ToPolyTraitRef, Ty};
3435
use middle::infer;
3536
use middle::infer::{InferCtxt, TypeFreshener};
@@ -44,7 +45,7 @@ use util::ppaux::Repr;
4445
pub struct SelectionContext<'cx, 'tcx:'cx> {
4546
infcx: &'cx InferCtxt<'cx, 'tcx>,
4647
param_env: &'cx ty::ParameterEnvironment<'tcx>,
47-
typer: &'cx (Typer<'tcx>+'cx),
48+
closure_typer: &'cx (ty::UnboxedClosureTyper<'tcx>+'cx),
4849

4950
/// Freshener used specifically for skolemizing entries on the
5051
/// obligation stack. This ensures that all entries on the stack
@@ -177,25 +178,25 @@ enum EvaluationResult<'tcx> {
177178
impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
178179
pub fn new(infcx: &'cx InferCtxt<'cx, 'tcx>,
179180
param_env: &'cx ty::ParameterEnvironment<'tcx>,
180-
typer: &'cx Typer<'tcx>)
181+
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
181182
-> SelectionContext<'cx, 'tcx> {
182183
SelectionContext {
183184
infcx: infcx,
184185
param_env: param_env,
185-
typer: typer,
186+
closure_typer: closure_typer,
186187
freshener: infcx.freshener(),
187188
intercrate: false,
188189
}
189190
}
190191

191192
pub fn intercrate(infcx: &'cx InferCtxt<'cx, 'tcx>,
192193
param_env: &'cx ty::ParameterEnvironment<'tcx>,
193-
typer: &'cx Typer<'tcx>)
194+
closure_typer: &'cx ty::UnboxedClosureTyper<'tcx>)
194195
-> SelectionContext<'cx, 'tcx> {
195196
SelectionContext {
196197
infcx: infcx,
197198
param_env: param_env,
198-
typer: typer,
199+
closure_typer: closure_typer,
199200
freshener: infcx.freshener(),
200201
intercrate: true,
201202
}
@@ -918,15 +919,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
918919
kind,
919920
obligation.repr(self.tcx()));
920921

921-
let closure_kind = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
922-
Some(closure) => closure.kind,
923-
None => {
924-
self.tcx().sess.span_bug(
925-
obligation.cause.span,
926-
format!("No entry for unboxed closure: {}",
927-
closure_def_id.repr(self.tcx()))[]);
928-
}
929-
};
922+
let closure_kind = self.closure_typer.unboxed_closure_kind(closure_def_id);
930923

931924
debug!("closure_kind = {}", closure_kind);
932925

@@ -1398,32 +1391,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13981391
return Ok(ParameterBuiltin);
13991392
}
14001393

1401-
match self.tcx().freevars.borrow().get(&def_id.node) {
1402-
None => {
1403-
// No upvars.
1404-
Ok(If(Vec::new()))
1394+
match self.closure_typer.unboxed_closure_upvars(def_id, substs) {
1395+
Some(upvars) => {
1396+
Ok(If(upvars.iter().map(|c| c.ty).collect()))
14051397
}
1406-
1407-
Some(freevars) => {
1408-
let tys: Vec<Ty> =
1409-
freevars
1410-
.iter()
1411-
.map(|freevar| {
1412-
let freevar_def_id = freevar.def.def_id();
1413-
self.typer.node_ty(freevar_def_id.node).subst(self.tcx(), substs)
1414-
})
1415-
.collect();
1416-
Ok(If(tys))
1398+
None => {
1399+
Ok(AmbiguousBuiltin)
14171400
}
14181401
}
14191402
}
14201403

14211404
ty::ty_struct(def_id, substs) => {
14221405
let types: Vec<Ty> =
1423-
ty::struct_fields(self.tcx(), def_id, substs)
1424-
.iter()
1425-
.map(|f| f.mt.ty)
1426-
.collect();
1406+
ty::struct_fields(self.tcx(), def_id, substs).iter()
1407+
.map(|f| f.mt.ty)
1408+
.collect();
14271409
nominal(self, bound, def_id, types)
14281410
}
14291411

@@ -1798,27 +1780,22 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17981780
closure_def_id.repr(self.tcx()),
17991781
substs.repr(self.tcx()));
18001782

1801-
let closure_type = match self.typer.unboxed_closures().borrow().get(&closure_def_id) {
1802-
Some(closure) => closure.closure_type.clone(),
1803-
None => {
1804-
self.tcx().sess.span_bug(
1805-
obligation.cause.span,
1806-
format!("No entry for unboxed closure: {}",
1807-
closure_def_id.repr(self.tcx()))[]);
1808-
}
1809-
};
1783+
let closure_type = self.closure_typer.unboxed_closure_type(closure_def_id, substs);
1784+
1785+
debug!("confirm_unboxed_closure_candidate: closure_def_id={} closure_type={}",
1786+
closure_def_id.repr(self.tcx()),
1787+
closure_type.repr(self.tcx()));
18101788

18111789
let closure_sig = &closure_type.sig;
18121790
let arguments_tuple = closure_sig.0.inputs[0];
1813-
let substs =
1791+
let trait_substs =
18141792
Substs::new_trait(
1815-
vec![arguments_tuple.subst(self.tcx(), substs),
1816-
closure_sig.0.output.unwrap().subst(self.tcx(), substs)],
1793+
vec![arguments_tuple, closure_sig.0.output.unwrap()],
18171794
vec![],
18181795
obligation.self_ty());
18191796
let trait_ref = ty::Binder(Rc::new(ty::TraitRef {
18201797
def_id: obligation.predicate.def_id(),
1821-
substs: self.tcx().mk_substs(substs),
1798+
substs: self.tcx().mk_substs(trait_substs),
18221799
}));
18231800

18241801
debug!("confirm_unboxed_closure_candidate(closure_def_id={}, trait_ref={})",
@@ -2100,7 +2077,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
21002077
}
21012078
}
21022079

2103-
fn impl_predicates(&self,
2080+
fn impl_predicates(&mut self,
21042081
cause: ObligationCause<'tcx>,
21052082
recursion_depth: uint,
21062083
impl_def_id: ast::DefId,
@@ -2111,8 +2088,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
21112088
{
21122089
let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
21132090
let bounds = impl_generics.to_bounds(self.tcx(), impl_substs);
2114-
let bounds = self.infcx().plug_leaks(skol_map, snapshot, &bounds);
2115-
util::predicates_for_generics(self.tcx(), cause, recursion_depth, &bounds)
2091+
let normalized_bounds =
2092+
project::normalize_with_depth(self, cause.clone(), recursion_depth, &bounds);
2093+
let normalized_bounds =
2094+
self.infcx().plug_leaks(skol_map, snapshot, &normalized_bounds);
2095+
let mut impl_obligations =
2096+
util::predicates_for_generics(self.tcx(),
2097+
cause,
2098+
recursion_depth,
2099+
&normalized_bounds.value);
2100+
for obligation in normalized_bounds.obligations.into_iter() {
2101+
impl_obligations.push(TypeSpace, obligation);
2102+
}
2103+
impl_obligations
21162104
}
21172105

21182106
fn fn_family_trait_kind(&self,

0 commit comments

Comments
 (0)