Skip to content

Commit 099d03a

Browse files
committed
---
yaml --- r: 178811 b: refs/heads/tmp c: 0431134 h: refs/heads/master i: 178809: 91666da 178807: 1f47072 v: v3
1 parent b2f17a4 commit 099d03a

File tree

24 files changed

+156
-137
lines changed

24 files changed

+156
-137
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,4 @@ refs/heads/building: 126db549b038c84269a1e4fe46f051b2c15d6970
3434
refs/heads/beta: 44a287e6eb22ec3c2a687fc156813577464017f7
3535
refs/heads/windistfix: 7608dbad651f02e837ed05eef3d74a6662a6e928
3636
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
37-
refs/heads/tmp: 47f18659ff629792f49b5ed87e870687703831fe
37+
refs/heads/tmp: 04311341197ddabc420a8cffc0d26c12228d445b

branches/tmp/src/librustc/middle/check_loop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl<'a, 'v> Visitor<'v> for CheckLoopVisitor<'a> {
4545
ast::ExprLoop(ref b, _) => {
4646
self.with_context(Loop, |v| v.visit_block(&**b));
4747
}
48-
ast::ExprClosure(_, _, _, ref b) => {
48+
ast::ExprClosure(_, _, ref b) => {
4949
self.with_context(Closure, |v| v.visit_block(&**b));
5050
}
5151
ast::ExprBreak(_) => self.require_loop("break", e.span),

branches/tmp/src/librustc/middle/liveness.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
959959
self.propagate_through_expr(&**e, succ)
960960
}
961961

962-
ast::ExprClosure(_, _, _, ref blk) => {
962+
ast::ExprClosure(_, _, ref blk) => {
963963
debug!("{} is an ExprClosure",
964964
expr_to_string(expr));
965965

branches/tmp/src/librustc/middle/mem_categorization.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
739739
};
740740

741741
match fn_expr.node {
742-
ast::ExprClosure(_, _, _, ref body) => body.id,
742+
ast::ExprClosure(_, _, ref body) => body.id,
743743
_ => unreachable!()
744744
}
745745
};

branches/tmp/src/librustc_borrowck/borrowck/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ pub fn closure_to_block(closure_id: ast::NodeId,
324324
tcx: &ty::ctxt) -> ast::NodeId {
325325
match tcx.map.get(closure_id) {
326326
ast_map::NodeExpr(expr) => match expr.node {
327-
ast::ExprClosure(_, _, _, ref block) => {
327+
ast::ExprClosure(_, _, ref block) => {
328328
block.id
329329
}
330330
_ => {

branches/tmp/src/librustc_resolve/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4521,7 +4521,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
45214521
visit::walk_expr(self, expr);
45224522
}
45234523

4524-
ExprClosure(_, _, ref fn_decl, ref block) => {
4524+
ExprClosure(_, ref fn_decl, ref block) => {
45254525
self.resolve_function(ClosureRibKind(expr.id),
45264526
Some(&**fn_decl), NoTypeParameters,
45274527
&**block);

branches/tmp/src/librustc_trans/save/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1394,7 +1394,7 @@ impl<'l, 'tcx, 'v> Visitor<'v> for DxrVisitor<'l, 'tcx> {
13941394
type, found {:?}", ty)[]),
13951395
}
13961396
},
1397-
ast::ExprClosure(_, _, ref decl, ref body) => {
1397+
ast::ExprClosure(_, ref decl, ref body) => {
13981398
if generated_code(body.span) {
13991399
return
14001400
}

branches/tmp/src/librustc_trans/trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ fn build_cfg(tcx: &ty::ctxt, id: ast::NodeId) -> (ast::NodeId, Option<cfg::CFG>)
13401340
}
13411341
Some(ast_map::NodeExpr(e)) => {
13421342
match e.node {
1343-
ast::ExprClosure(_, _, _, ref blk) => {
1343+
ast::ExprClosure(_, _, ref blk) => {
13441344
blk
13451345
}
13461346
_ => tcx.sess.bug("unexpected expr variant in has_nested_returns")

branches/tmp/src/librustc_trans/trans/debuginfo.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
12831283
}
12841284
ast_map::NodeExpr(ref expr) => {
12851285
match expr.node {
1286-
ast::ExprClosure(_, _, ref fn_decl, ref top_level_block) => {
1286+
ast::ExprClosure(_, ref fn_decl, ref top_level_block) => {
12871287
let name = format!("fn{}", token::gensym("fn"));
12881288
let name = token::str_to_ident(&name[]);
12891289
(name, &**fn_decl,
@@ -3595,7 +3595,7 @@ fn create_scope_map(cx: &CrateContext,
35953595
})
35963596
}
35973597

3598-
ast::ExprClosure(_, _, ref decl, ref block) => {
3598+
ast::ExprClosure(_, ref decl, ref block) => {
35993599
with_new_scope(cx,
36003600
block.span,
36013601
scope_stack,

branches/tmp/src/librustc_trans/trans/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1094,7 +1094,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
10941094
ast::ExprVec(..) | ast::ExprRepeat(..) => {
10951095
tvec::trans_fixed_vstore(bcx, expr, dest)
10961096
}
1097-
ast::ExprClosure(_, _, ref decl, ref body) => {
1097+
ast::ExprClosure(_, ref decl, ref body) => {
10981098
closure::trans_closure_expr(bcx, &**decl, &**body, expr.id, dest)
10991099
}
11001100
ast::ExprCall(ref f, ref args) => {

branches/tmp/src/librustc_typeck/check/closure.rs

Lines changed: 90 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -25,46 +25,21 @@ use util::ppaux::Repr;
2525
pub fn check_expr_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
2626
expr: &ast::Expr,
2727
_capture: ast::CaptureClause,
28-
opt_kind: Option<ast::ClosureKind>,
2928
decl: &'tcx ast::FnDecl,
3029
body: &'tcx ast::Block,
3130
expected: Expectation<'tcx>) {
3231
debug!("check_expr_closure(expr={},expected={})",
3332
expr.repr(fcx.tcx()),
3433
expected.repr(fcx.tcx()));
3534

36-
let expected_sig_and_kind = expected.to_option(fcx).and_then(|ty| {
37-
deduce_expectations_from_expected_type(fcx, ty)
38-
});
39-
40-
match opt_kind {
41-
None => {
42-
// If users didn't specify what sort of closure they want,
43-
// examine the expected type. For now, if we see explicit
44-
// evidence than an unboxed closure is desired, we'll use
45-
// that. Otherwise, we leave it unspecified, to be filled
46-
// in by upvar inference.
47-
match expected_sig_and_kind {
48-
None => { // don't have information about the kind, request explicit annotation
49-
check_closure(fcx, expr, None, decl, body, None);
50-
},
51-
Some((sig, kind)) => {
52-
check_closure(fcx, expr, Some(kind), decl, body, Some(sig));
53-
}
54-
}
55-
}
56-
57-
Some(kind) => {
58-
let kind = match kind {
59-
ast::FnClosureKind => ty::FnClosureKind,
60-
ast::FnMutClosureKind => ty::FnMutClosureKind,
61-
ast::FnOnceClosureKind => ty::FnOnceClosureKind,
62-
};
63-
64-
let expected_sig = expected_sig_and_kind.map(|t| t.0);
65-
check_closure(fcx, expr, Some(kind), decl, body, expected_sig);
66-
}
67-
}
35+
// It's always helpful for inference if we know the kind of
36+
// closure sooner rather than later, so first examine the expected
37+
// type, and see if can glean a closure kind from there.
38+
let (expected_sig,expected_kind) = match expected.to_option(fcx) {
39+
Some(ty) => deduce_expectations_from_expected_type(fcx, ty),
40+
None => (None, None)
41+
};
42+
check_closure(fcx, expr, expected_kind, decl, body, expected_sig)
6843
}
6944

7045
fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
@@ -133,55 +108,92 @@ fn check_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
133108
fn deduce_expectations_from_expected_type<'a,'tcx>(
134109
fcx: &FnCtxt<'a,'tcx>,
135110
expected_ty: Ty<'tcx>)
136-
-> Option<(ty::FnSig<'tcx>,ty::ClosureKind)>
111+
-> (Option<ty::FnSig<'tcx>>,Option<ty::ClosureKind>)
137112
{
113+
debug!("deduce_expectations_from_expected_type(expected_ty={})",
114+
expected_ty.repr(fcx.tcx()));
115+
138116
match expected_ty.sty {
139117
ty::ty_trait(ref object_type) => {
140118
let proj_bounds = object_type.projection_bounds_with_self_ty(fcx.tcx(),
141119
fcx.tcx().types.err);
142-
proj_bounds.iter()
143-
.filter_map(|pb| deduce_expectations_from_projection(fcx, pb))
144-
.next()
120+
let expectations =
121+
proj_bounds.iter()
122+
.filter_map(|pb| deduce_expectations_from_projection(fcx, pb))
123+
.next();
124+
125+
match expectations {
126+
Some((sig, kind)) => (Some(sig), Some(kind)),
127+
None => (None, None)
128+
}
145129
}
146130
ty::ty_infer(ty::TyVar(vid)) => {
147131
deduce_expectations_from_obligations(fcx, vid)
148132
}
149133
_ => {
150-
None
134+
(None, None)
151135
}
152136
}
153137
}
154138

155139
fn deduce_expectations_from_obligations<'a,'tcx>(
156140
fcx: &FnCtxt<'a,'tcx>,
157141
expected_vid: ty::TyVid)
158-
-> Option<(ty::FnSig<'tcx>, ty::ClosureKind)>
142+
-> (Option<ty::FnSig<'tcx>>, Option<ty::ClosureKind>)
159143
{
160144
let fulfillment_cx = fcx.inh.fulfillment_cx.borrow();
161145
// Here `expected_ty` is known to be a type inference variable.
162146

163-
fulfillment_cx.pending_obligations()
164-
.iter()
165-
.filter_map(|obligation| {
166-
match obligation.predicate {
167-
ty::Predicate::Projection(ref proj_predicate) => {
168-
let trait_ref = proj_predicate.to_poly_trait_ref();
169-
let self_ty = fcx.infcx().shallow_resolve(trait_ref.self_ty());
170-
match self_ty.sty {
171-
ty::ty_infer(ty::TyVar(v)) if expected_vid == v => {
172-
deduce_expectations_from_projection(fcx, proj_predicate)
173-
}
174-
_ => {
175-
None
176-
}
177-
}
178-
}
179-
_ => {
180-
None
181-
}
182-
}
183-
})
184-
.next()
147+
let expected_sig_and_kind =
148+
fulfillment_cx
149+
.pending_obligations()
150+
.iter()
151+
.filter_map(|obligation| {
152+
debug!("deduce_expectations_from_obligations: obligation.predicate={}",
153+
obligation.predicate.repr(fcx.tcx()));
154+
155+
match obligation.predicate {
156+
// Given a Projection predicate, we can potentially infer
157+
// the complete signature.
158+
ty::Predicate::Projection(ref proj_predicate) => {
159+
let trait_ref = proj_predicate.to_poly_trait_ref();
160+
self_type_matches_expected_vid(fcx, trait_ref, expected_vid)
161+
.and_then(|_| deduce_expectations_from_projection(fcx, proj_predicate))
162+
}
163+
_ => {
164+
None
165+
}
166+
}
167+
})
168+
.next();
169+
170+
match expected_sig_and_kind {
171+
Some((sig, kind)) => { return (Some(sig), Some(kind)); }
172+
None => { }
173+
}
174+
175+
// Even if we can't infer the full signature, we may be able to
176+
// infer the kind. This can occur if there is a trait-reference
177+
// like `F : Fn<A>`.
178+
let expected_kind =
179+
fulfillment_cx
180+
.pending_obligations()
181+
.iter()
182+
.filter_map(|obligation| {
183+
let opt_trait_ref = match obligation.predicate {
184+
ty::Predicate::Projection(ref data) => Some(data.to_poly_trait_ref()),
185+
ty::Predicate::Trait(ref data) => Some(data.to_poly_trait_ref()),
186+
ty::Predicate::Equate(..) => None,
187+
ty::Predicate::RegionOutlives(..) => None,
188+
ty::Predicate::TypeOutlives(..) => None,
189+
};
190+
opt_trait_ref
191+
.and_then(|trait_ref| self_type_matches_expected_vid(fcx, trait_ref, expected_vid))
192+
.and_then(|trait_ref| fcx.tcx().lang_items.fn_trait_kind(trait_ref.def_id()))
193+
})
194+
.next();
195+
196+
(None, expected_kind)
185197
}
186198

187199
/// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
@@ -229,3 +241,20 @@ fn deduce_expectations_from_projection<'a,'tcx>(
229241
return Some((fn_sig, kind));
230242
}
231243

244+
fn self_type_matches_expected_vid<'a,'tcx>(
245+
fcx: &FnCtxt<'a,'tcx>,
246+
trait_ref: ty::PolyTraitRef<'tcx>,
247+
expected_vid: ty::TyVid)
248+
-> Option<ty::PolyTraitRef<'tcx>>
249+
{
250+
let self_ty = fcx.infcx().shallow_resolve(trait_ref.self_ty());
251+
debug!("self_type_matches_expected_vid(trait_ref={}, self_ty={})",
252+
trait_ref.repr(fcx.tcx()),
253+
self_ty.repr(fcx.tcx()));
254+
match self_ty.sty {
255+
ty::ty_infer(ty::TyVar(v)) if expected_vid == v => Some(trait_ref),
256+
_ => None,
257+
}
258+
}
259+
260+

branches/tmp/src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3736,8 +3736,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
37363736
ast::ExprMatch(ref discrim, ref arms, match_src) => {
37373737
_match::check_match(fcx, expr, &**discrim, arms.as_slice(), expected, match_src);
37383738
}
3739-
ast::ExprClosure(capture, opt_kind, ref decl, ref body) => {
3740-
closure::check_expr_closure(fcx, expr, capture, opt_kind, &**decl, &**body, expected);
3739+
ast::ExprClosure(capture, ref decl, ref body) => {
3740+
closure::check_expr_closure(fcx, expr, capture, &**decl, &**body, expected);
37413741
}
37423742
ast::ExprBlock(ref b) => {
37433743
check_block_with_expected(fcx, &**b, expected);

branches/tmp/src/librustc_typeck/check/regionck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
638638
visit::walk_expr(rcx, expr);
639639
}
640640

641-
ast::ExprClosure(_, _, _, ref body) => {
641+
ast::ExprClosure(_, _, ref body) => {
642642
check_expr_fn_block(rcx, expr, &**body);
643643
}
644644

branches/tmp/src/librustc_typeck/check/upvar.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ struct SeedBorrowKind<'a,'tcx:'a> {
8383
impl<'a, 'tcx, 'v> Visitor<'v> for SeedBorrowKind<'a, 'tcx> {
8484
fn visit_expr(&mut self, expr: &ast::Expr) {
8585
match expr.node {
86-
ast::ExprClosure(cc, _, _, ref body) => {
86+
ast::ExprClosure(cc, _, ref body) => {
8787
self.check_closure(expr, cc, &**body);
8888
}
8989

branches/tmp/src/librustc_typeck/check/writeback.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ impl<'cx, 'tcx, 'v> Visitor<'v> for WritebackCx<'cx, 'tcx> {
118118
MethodCall::expr(e.id));
119119

120120
match e.node {
121-
ast::ExprClosure(_, _, ref decl, _) => {
121+
ast::ExprClosure(_, ref decl, _) => {
122122
for input in &decl.inputs {
123123
let _ = self.visit_node_id(ResolvingExpr(e.span),
124124
input.id);

branches/tmp/src/libsyntax/ast.rs

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ pub use self::TraitItem::*;
4848
pub use self::Ty_::*;
4949
pub use self::TyParamBound::*;
5050
pub use self::UintTy::*;
51-
pub use self::ClosureKind::*;
5251
pub use self::UnOp::*;
5352
pub use self::UnsafeSource::*;
5453
pub use self::VariantKind::*;
@@ -736,7 +735,7 @@ pub enum Expr_ {
736735
// FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
737736
ExprLoop(P<Block>, Option<Ident>),
738737
ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
739-
ExprClosure(CaptureClause, Option<ClosureKind>, P<FnDecl>, P<Block>),
738+
ExprClosure(CaptureClause, P<FnDecl>, P<Block>),
740739
ExprBlock(P<Block>),
741740

742741
ExprAssign(P<Expr>, P<Expr>),
@@ -1687,13 +1686,6 @@ impl ForeignItem_ {
16871686
}
16881687
}
16891688

1690-
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
1691-
pub enum ClosureKind {
1692-
FnClosureKind,
1693-
FnMutClosureKind,
1694-
FnOnceClosureKind,
1695-
}
1696-
16971689
/// The data we save and restore about an inlined item or method. This is not
16981690
/// part of the AST that we parse from a file, but it becomes part of the tree
16991691
/// that we trans.

branches/tmp/src/libsyntax/ast_map/blocks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ impl<'a> FnLikeNode<'a> {
218218
}
219219
}
220220
ast_map::NodeExpr(e) => match e.node {
221-
ast::ExprClosure(_, _, ref decl, ref block) =>
221+
ast::ExprClosure(_, ref decl, ref block) =>
222222
closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
223223
_ => panic!("expr FnLikeNode that is not fn-like"),
224224
},

branches/tmp/src/libsyntax/ext/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -876,14 +876,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
876876

877877
fn lambda_fn_decl(&self, span: Span,
878878
fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> P<ast::Expr> {
879-
self.expr(span, ast::ExprClosure(ast::CaptureByRef, None, fn_decl, blk))
879+
self.expr(span, ast::ExprClosure(ast::CaptureByRef, fn_decl, blk))
880880
}
881881
fn lambda(&self, span: Span, ids: Vec<ast::Ident>, blk: P<ast::Block>) -> P<ast::Expr> {
882882
let fn_decl = self.fn_decl(
883883
ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
884884
self.ty_infer(span));
885885

886-
self.expr(span, ast::ExprClosure(ast::CaptureByRef, None, fn_decl, blk))
886+
self.expr(span, ast::ExprClosure(ast::CaptureByRef, fn_decl, blk))
887887
}
888888
fn lambda0(&self, span: Span, blk: P<ast::Block>) -> P<ast::Expr> {
889889
self.lambda(span, Vec::new(), blk)

0 commit comments

Comments
 (0)