Skip to content

Commit d1f4e7d

Browse files
committed
---
yaml --- r: 48603 b: refs/heads/snap-stage3 c: a363862 h: refs/heads/master i: 48601: 08e5c5a 48599: 1e8654e v: v3
1 parent 9e913b2 commit d1f4e7d

File tree

3 files changed

+48
-62
lines changed

3 files changed

+48
-62
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: 3bbcac322669cff3abde5be937cc4ec3860f3985
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
4-
refs/heads/snap-stage3: 1d8596d400b245143df4a421654d7a94a8b4c1e1
4+
refs/heads/snap-stage3: a36386210293cf12f771adb6bc775a45cab6b4da
55
refs/heads/try: 2a8fb58d79e685d5ca07b039badcf2ae3ef077ea
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b

branches/snap-stage3/src/librustc/middle/typeck/check/mod.rs

Lines changed: 39 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -162,17 +162,7 @@ pub struct inherited {
162162
adjustments: HashMap<ast::node_id, @ty::AutoAdjustment>
163163
}
164164

165-
pub enum FnKind {
166-
// This is a for-closure. The ty::t is the return type of the
167-
// enclosing function.
168-
ForLoop(ty::t),
169-
170-
// A do-closure.
171-
DoBlock,
172-
173-
// A normal closure or fn item.
174-
Vanilla
175-
}
165+
pub enum FnKind { ForLoop, DoBlock, Vanilla }
176166

177167
pub struct FnCtxt {
178168
// var_bindings, locals and next_var_id are shared
@@ -260,14 +250,8 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt,
260250
let fty = ty::node_id_to_type(ccx.tcx, id);
261251
match ty::get(fty).sty {
262252
ty::ty_bare_fn(ref fn_ty) => {
263-
let fcx =
264-
check_fn(ccx, self_info, fn_ty.purity,
265-
&fn_ty.sig, decl, body, Vanilla,
266-
@Nil, blank_inherited(ccx));;
267-
268-
vtable::resolve_in_block(fcx, body);
269-
regionck::regionck_fn(fcx, body);
270-
writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info);
253+
check_fn(ccx, self_info, fn_ty.purity, None,
254+
&fn_ty.sig, decl, body, Vanilla, None)
271255
}
272256
_ => ccx.tcx.sess.impossible_case(body.span,
273257
"check_bare_fn: function type expected")
@@ -277,34 +261,26 @@ pub fn check_bare_fn(ccx: @mut CrateCtxt,
277261
pub fn check_fn(ccx: @mut CrateCtxt,
278262
+self_info: Option<SelfInfo>,
279263
purity: ast::purity,
264+
sigil: Option<ast::Sigil>,
280265
fn_sig: &ty::FnSig,
281266
decl: &ast::fn_decl,
282267
body: &ast::blk,
283268
fn_kind: FnKind,
284-
inherited_isr: isr_alist,
285-
inherited: @inherited) -> @mut FnCtxt
286-
{
287-
/*!
288-
*
289-
* Helper used by check_bare_fn and check_expr_fn. Does the
290-
* grungy work of checking a function body and returns the
291-
* function context used for that purpose, since in the case of a
292-
* fn item there is still a bit more to do.
293-
*
294-
* - ...
295-
* - inherited_isr: regions in scope from the enclosing fn (if any)
296-
* - inherited: other fields inherited from the enclosing fn (if any)
297-
*/
298-
269+
old_fcx: Option<@mut FnCtxt>) {
299270
let tcx = ccx.tcx;
271+
let indirect_ret = match fn_kind {
272+
ForLoop => true, _ => false
273+
};
300274

301275
// ______________________________________________________________________
302276
// First, we have to replace any bound regions in the fn and self
303277
// types with free ones. The free region references will be bound
304278
// the node_id of the body block.
305279

306280
let (isr, self_info, fn_sig) = {
307-
replace_bound_regions_in_fn_sig(tcx, inherited_isr, self_info, fn_sig,
281+
let old_isr = option::map_default(&old_fcx, @Nil,
282+
|fcx| fcx.in_scope_regions);
283+
replace_bound_regions_in_fn_sig(tcx, old_isr, self_info, fn_sig,
308284
|br| ty::re_free(body.node.id, br))
309285
};
310286

@@ -320,13 +296,23 @@ pub fn check_fn(ccx: @mut CrateCtxt,
320296
// Create the function context. This is either derived from scratch or,
321297
// in the case of function expressions, based on the outer context.
322298
let fcx: @mut FnCtxt = {
323-
// In a for-loop, you have an 'indirect return' because return
324-
// does not return out of the directly enclosing fn
325-
let indirect_ret_ty = match fn_kind {
326-
ForLoop(t) => Some(t),
327-
DoBlock | Vanilla => None
299+
let (purity, inherited) = match old_fcx {
300+
None => (purity, blank_inherited(ccx)),
301+
Some(fcx) => {
302+
(ty::determine_inherited_purity(fcx.purity, purity,
303+
sigil.get()),
304+
fcx.inh)
305+
}
328306
};
329307

308+
let indirect_ret_ty = if indirect_ret {
309+
let ofcx = old_fcx.get();
310+
match ofcx.indirect_ret_ty {
311+
Some(t) => Some(t),
312+
None => Some(ofcx.ret_ty)
313+
}
314+
} else { None };
315+
330316
@mut FnCtxt {
331317
self_info: self_info,
332318
ret_ty: ret_ty,
@@ -384,7 +370,15 @@ pub fn check_fn(ccx: @mut CrateCtxt,
384370
fcx.write_ty(input.id, *arg);
385371
}
386372

387-
return fcx;
373+
// If we don't have any enclosing function scope, it is time to
374+
// force any remaining type vars to be resolved.
375+
// If we have an enclosing function scope, our type variables will be
376+
// resolved when the enclosing scope finishes up.
377+
if old_fcx.is_none() {
378+
vtable::resolve_in_block(fcx, body);
379+
regionck::regionck_fn(fcx, body);
380+
writeback::resolve_type_vars_in_fn(fcx, decl, body, self_info);
381+
}
388382

389383
fn gather_locals(fcx: @mut FnCtxt,
390384
decl: &ast::fn_decl,
@@ -909,7 +903,7 @@ pub impl FnCtxt {
909903
a: ty::t,
910904
err: &ty::type_err) {
911905
match self.fn_kind {
912-
ForLoop(_) if !ty::type_is_bool(e) && !ty::type_is_nil(a) =>
906+
ForLoop if !ty::type_is_bool(e) && !ty::type_is_nil(a) =>
913907
self.tcx().sess.span_err(sp, fmt!("A for-loop body must \
914908
return (), but it returns %s here. \
915909
Perhaps you meant to write a `do`-block?",
@@ -1673,15 +1667,10 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
16731667

16741668
fcx.write_ty(expr.id, fty);
16751669

1676-
let inherited_purity =
1677-
ty::determine_inherited_purity(fcx.purity, purity,
1678-
fn_ty.sigil);
1679-
16801670
// We inherit the same self info as the enclosing scope,
16811671
// since the function we're checking might capture `self`
1682-
check_fn(fcx.ccx, fcx.self_info, inherited_purity,
1683-
&fn_ty.sig, decl, body, fn_kind,
1684-
fcx.in_scope_regions, fcx.inh);
1672+
check_fn(fcx.ccx, fcx.self_info, fn_ty.purity, Some(fn_ty.sigil),
1673+
&fn_ty.sig, decl, body, fn_kind, Some(fcx));
16851674
}
16861675

16871676

@@ -2091,13 +2080,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
20912080
// derived errors. If we passed in ForLoop in the
20922081
// error case, we'd potentially emit a spurious error
20932082
// message because of the indirect_ret_ty.
2094-
let fn_kind = if err_happened {
2095-
Vanilla
2096-
} else {
2097-
let indirect_ret_ty =
2098-
fcx.indirect_ret_ty.get_or_default(fcx.ret_ty);
2099-
ForLoop(indirect_ret_ty)
2100-
};
2083+
let fn_kind = if err_happened {Vanilla} else {ForLoop};
21012084
check_expr_fn(fcx, loop_body, None,
21022085
decl, body, fn_kind, Some(inner_ty));
21032086
demand::suptype(fcx, loop_body.span,

branches/snap-stage3/src/libstd/getopts.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
1+
// Copyright 2011-2013 The Rust Project Developers. See the COPYRIGHT
22
// file at the top-level directory of this distribution and at
33
// http://rust-lang.org/COPYRIGHT.
44
//
@@ -29,8 +29,10 @@
2929
* The following example shows simple command line parsing for an application
3030
* that requires an input file to be specified, accepts an optional output
3131
* file name following -o, and accepts both -h and --help as optional flags.
32-
* extern mod std;
33-
* use std::getopts::*;
32+
*
33+
* ```
34+
* extern mod std;
35+
* use std::getopts::*;
3436
*
3537
* fn do_work(in: &str, out: Option<~str>) {
3638
* io::println(in);
@@ -58,21 +60,22 @@
5860
* ];
5961
* let matches = match getopts(vec::tail(args), opts) {
6062
* result::Ok(m) => { m }
61-
* result::Err(f) => { fail fail_str(f) }
63+
* result::Err(f) => { fail!(fail_str(f)) }
6264
* };
6365
* if opt_present(&matches, "h") || opt_present(&matches, "help") {
6466
* print_usage(program, opts);
6567
* return;
6668
* }
6769
* let output = opt_maybe_str(&matches, "o");
6870
* let input: &str = if !matches.free.is_empty() {
69-
* matches.free[0]
71+
* copy matches.free[0]
7072
* } else {
7173
* print_usage(program, opts);
7274
* return;
7375
* };
7476
* do_work(input, output);
7577
* }
78+
* ```
7679
*/
7780

7881
use core::cmp::Eq;

0 commit comments

Comments
 (0)