Skip to content

Commit bfcd6e2

Browse files
committed
---
yaml --- r: 16104 b: refs/heads/try c: e6b9db0 h: refs/heads/master v: v3
1 parent 1f8c991 commit bfcd6e2

File tree

5 files changed

+120
-187
lines changed

5 files changed

+120
-187
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
refs/heads/master: 61b1875c16de39c166b0f4d54bba19f9c6777d1a
33
refs/heads/snap-stage1: e33de59e47c5076a89eadeb38f4934f58a3618a6
44
refs/heads/snap-stage3: 4a81779abd786ff22d71434c6d9a5917ea4cdfff
5-
refs/heads/try: b744f52620821ed665eb1ac9c36f862a0b72eaf4
5+
refs/heads/try: e6b9db08841c5d215c56790e35f951a99275001d
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105

branches/try/src/rustc/middle/typeck/check.rs

Lines changed: 62 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ import astconv::{ast_conv, ast_ty_to_ty};
7070
import collect::{methods}; // ccx.to_ty()
7171
import method::{methods}; // methods for method::lookup
7272
import middle::ty::tys_in_fn_ty;
73-
import regionmanip::{universally_quantify_from_sty,
73+
import regionmanip::{replace_bound_regions_in_fn_ty,
7474
region_of, replace_bound_regions,
7575
collect_bound_regions_in_tys};
7676
import rscope::*;
@@ -84,7 +84,6 @@ type fn_ctxt =
8484
// Used by loop bodies that return from the outer function
8585
indirect_ret_ty: option<ty::t>,
8686
purity: ast::purity,
87-
proto: ast::proto,
8887
infcx: infer::infer_ctxt,
8988
locals: hashmap<ast::node_id, ty_vid>,
9089

@@ -128,55 +127,41 @@ fn check_bare_fn(ccx: @crate_ctxt,
128127
id: ast::node_id,
129128
self_ty: option<ty::t>) {
130129
let fty = ty::node_id_to_type(ccx.tcx, id);
131-
let ret_ty = ty::ty_fn_ret(fty);
132-
let arg_tys = vec::map(ty::ty_fn_args(fty)) {|a| a.ty };
133-
check_fn(ccx, ast::proto_bare, decl, body,
134-
ret_ty, arg_tys, false, none, self_ty);
130+
let fn_ty = alt check ty::get(fty).struct { ty::ty_fn(f) {f} };
131+
check_fn(ccx, self_ty, fn_ty, decl, body, false, none);
135132
}
136133

137134
fn check_fn(ccx: @crate_ctxt,
138-
proto: ast::proto,
135+
self_ty: option<ty::t>,
136+
fn_ty: ty::fn_ty,
139137
decl: ast::fn_decl,
140138
body: ast::blk,
141-
ret_ty: ty::t,
142-
arg_tys: [ty::t],
143139
indirect_ret: bool,
144-
old_fcx: option<@fn_ctxt>,
145-
self_ty: option<ty::t>) {
140+
old_fcx: option<@fn_ctxt>) {
146141

147142
let tcx = ccx.tcx;
148143

149-
let isr = {
150-
// Find the list of in-scope regions. These are derived from the
151-
// various regions that are bound in the argument, return, and self
152-
// types. For each of those bound regions, we will create a mapping
153-
// to a free region tied to the node_id of this function. For an
154-
// in-depth discussion of why we must distinguish bound/free regions,
155-
// see the big comment in region.rs.
156-
let all_tys = arg_tys + [ret_ty] + self_ty.to_vec();
157-
let old_isr = option::map_default(old_fcx, @nil) {
158-
|fcx| fcx.in_scope_regions };
159-
collect_bound_regions_in_tys(tcx, old_isr, all_tys) {
160-
|br| ty::re_free(body.node.id, br) }
161-
};
144+
// ______________________________________________________________________
145+
// First, we have to replace any bound regions in the fn and self
146+
// types with free ones. The free region references will be bound
147+
// the node_id of the body block.
162148

163-
// Replace the bound regions that appear in the arg tys, ret ty, etc with
164-
// the free versions we just collected.
165-
let arg_tys = arg_tys.map {
166-
|arg_ty| replace_bound_regions(tcx, body.span, isr, arg_ty)
167-
};
168-
let ret_ty = {
169-
replace_bound_regions(tcx, body.span, isr, ret_ty)
170-
};
171-
let self_ty = option::map(self_ty) {
172-
|self_ty| replace_bound_regions(tcx, body.span, isr, self_ty)
149+
let {isr, self_ty, fn_ty} = {
150+
let old_isr = option::map_default(old_fcx, @nil,
151+
{ |fcx| fcx.in_scope_regions });
152+
replace_bound_regions_in_fn_ty(tcx, old_isr, self_ty, fn_ty,
153+
{ |br| ty::re_free(body.node.id, br) })
173154
};
174155

156+
let arg_tys = fn_ty.inputs.map { |a| a.ty };
157+
let ret_ty = fn_ty.output;
158+
175159
#debug["check_fn(arg_tys=%?, ret_ty=%?, self_ty=%?)",
176160
arg_tys.map {|a| ty_to_str(tcx, a) },
177161
ty_to_str(tcx, ret_ty),
178162
option::map(self_ty) {|st| ty_to_str(tcx, st) }];
179163

164+
// ______________________________________________________________________
180165
// Create the function context. This is either derived from scratch or,
181166
// in the case of function expressions, based on the outer context.
182167
let fcx: @fn_ctxt = {
@@ -211,7 +196,6 @@ fn check_fn(ccx: @crate_ctxt,
211196
ret_ty: ret_ty,
212197
indirect_ret_ty: indirect_ret_ty,
213198
purity: purity,
214-
proto: proto,
215199
infcx: infcx,
216200
locals: locals,
217201
mut blocks: [],
@@ -708,74 +692,66 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
708692
// A generic function to factor out common logic from call and bind
709693
// expressions.
710694
fn check_call_or_bind(
711-
fcx: @fn_ctxt, sp: span, call_expr_id: ast::node_id, fty: ty::t,
695+
fcx: @fn_ctxt, sp: span, call_expr_id: ast::node_id, in_fty: ty::t,
712696
args: [option<@ast::expr>]) -> {fty: ty::t, bot: bool} {
713697

714698
let mut bot = false;
715699

716700
// Replace all region parameters in the arguments and return
717701
// type with fresh region variables.
718702

719-
#debug["check_call_or_bind: before universal quant., fty=%s",
720-
fcx.infcx.ty_to_str(fty)];
703+
#debug["check_call_or_bind: before universal quant., in_fty=%s",
704+
fcx.infcx.ty_to_str(in_fty)];
721705

722706
// This is subtle: we expect `fty` to be a function type, which
723707
// normally introduce a level of binding. In this case, we want to
724708
// process the types bound by the function but not by any nested
725709
// functions. Therefore, we match one level of structure.
726-
let fty =
727-
alt structure_of(fcx, sp, fty) {
728-
sty @ ty::ty_fn(inner_fty) {
729-
let all_tys = tys_in_fn_ty(inner_fty);
730-
universally_quantify_from_sty(fcx, sp, all_tys, sty)
710+
let fn_ty =
711+
alt structure_of(fcx, sp, in_fty) {
712+
sty @ ty::ty_fn(fn_ty) {
713+
replace_bound_regions_in_fn_ty(
714+
fcx.ccx.tcx, @nil, none, fn_ty,
715+
{ |_br| fcx.infcx.next_region_var() }).fn_ty
731716
}
732717
sty {
733-
#debug["not a fn ty: %?", sty];
734-
735-
// if not a function type, we're gonna' report an error at
736-
// some point, since the user is trying to call this thing
737-
fty
718+
// I would like to make this span_err, but it's
719+
// really hard due to the way that expr_bind() is
720+
// written.
721+
fcx.ccx.tcx.sess.span_fatal(sp, "mismatched types: \
722+
expected function or native \
723+
function but found "
724+
+ fcx.infcx.ty_to_str(in_fty));
738725
}
739726
};
740727

728+
let fty = ty::mk_fn(fcx.tcx(), fn_ty);
741729
#debug["check_call_or_bind: after universal quant., fty=%s",
742730
fcx.infcx.ty_to_str(fty)];
743731

744732
let supplied_arg_count = vec::len(args);
745733

746-
// Grab the argument types
747-
let arg_tys = alt structure_of(fcx, sp, fty) {
748-
ty::ty_fn({inputs: arg_tys, output: ret_ty, _}) {
749-
let expected_arg_count = vec::len(arg_tys);
750-
if expected_arg_count == supplied_arg_count {
751-
arg_tys.map { |a| a.ty }
752-
} else {
753-
fcx.ccx.tcx.sess.span_err(
754-
sp, #fmt["this function takes %u parameter%s but %u \
755-
parameter%s supplied", expected_arg_count,
756-
if expected_arg_count == 1u {
757-
""
758-
} else {
759-
"s"
760-
},
761-
supplied_arg_count,
762-
if supplied_arg_count == 1u {
763-
" was"
764-
} else {
765-
"s were"
766-
}]);
767-
fcx.infcx.next_ty_vars(supplied_arg_count)
768-
}
769-
}
770-
771-
_ {
772-
// I would like to make this span_err, but it's really hard due to
773-
// the way that expr_bind() is written.
774-
fcx.ccx.tcx.sess.span_fatal(sp, "mismatched types: \
775-
expected function or native \
776-
function but found "
777-
+ fcx.infcx.ty_to_str(fty));
778-
}
734+
// Grab the argument types, supplying fresh type variables
735+
// if the wrong number of arguments were supplied
736+
let expected_arg_count = vec::len(fn_ty.inputs);
737+
let arg_tys = if expected_arg_count == supplied_arg_count {
738+
fn_ty.inputs.map { |a| a.ty }
739+
} else {
740+
fcx.ccx.tcx.sess.span_err(
741+
sp, #fmt["this function takes %u parameter%s but %u \
742+
parameter%s supplied", expected_arg_count,
743+
if expected_arg_count == 1u {
744+
""
745+
} else {
746+
"s"
747+
},
748+
supplied_arg_count,
749+
if supplied_arg_count == 1u {
750+
" was"
751+
} else {
752+
"s were"
753+
}]);
754+
fcx.infcx.next_ty_vars(supplied_arg_count)
779755
};
780756

781757
// Check the arguments.
@@ -1049,21 +1025,17 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
10491025
};
10501026

10511027
// construct the function type
1052-
let fty = ty::mk_fn(tcx,
1053-
astconv::ty_of_fn_decl(fcx, fcx, proto, decl,
1054-
expected_tys));
1028+
let fn_ty = astconv::ty_of_fn_decl(fcx, fcx, proto,
1029+
decl, expected_tys);
1030+
let fty = ty::mk_fn(tcx, fn_ty);
10551031

10561032
#debug("check_expr_fn_with_unifier %s fty=%s",
10571033
expr_to_str(expr), fcx.infcx.ty_to_str(fty));
10581034

10591035
fcx.write_ty(expr.id, fty);
10601036

1061-
let ret_ty = ty::ty_fn_ret(fty);
1062-
let arg_tys = vec::map(ty::ty_fn_args(fty)) {|a| a.ty };
1063-
1064-
check_fn(fcx.ccx, proto, decl, body,
1065-
ret_ty, arg_tys, is_loop_body, some(fcx),
1066-
fcx.self_ty);
1037+
check_fn(fcx.ccx, fcx.self_ty, fn_ty, decl, body,
1038+
is_loop_body, some(fcx));
10671039
}
10681040

10691041

@@ -1825,7 +1797,6 @@ fn check_const(ccx: @crate_ctxt, _sp: span, e: @ast::expr, id: ast::node_id) {
18251797
ret_ty: rty,
18261798
indirect_ret_ty: none,
18271799
purity: ast::pure_fn,
1828-
proto: ast::proto_box,
18291800
infcx: infer::new_infer_ctxt(ccx.tcx),
18301801
locals: int_hash(),
18311802
mut blocks: [],
@@ -1865,7 +1836,6 @@ fn check_enum_variants(ccx: @crate_ctxt,
18651836
ret_ty: rty,
18661837
indirect_ret_ty: none,
18671838
purity: ast::pure_fn,
1868-
proto: ast::proto_box,
18691839
infcx: infer::new_infer_ctxt(ccx.tcx),
18701840
locals: int_hash(),
18711841
mut blocks: [],

branches/try/src/rustc/middle/typeck/check/method.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/* Code to handle method lookups (which can be quite complex) */
22

33
import syntax::ast_map;
4-
import regionmanip::universally_quantify_from_sty;
54
import middle::typeck::infer::methods; // next_ty_vars
65

76
enum lookup = {

branches/try/src/rustc/middle/typeck/check/regionmanip.rs

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,40 @@ import syntax::print::pprust::{expr_to_str};
22

33
// Helper functions related to manipulating region types.
44

5-
// Extracts the bound regions from bound_tys and then replaces those same
6-
// regions in `sty` with fresh region variables, returning the resulting type.
7-
// Does not descend into fn types. This is used when deciding whether an impl
8-
// applies at a given call site.
9-
fn universally_quantify_from_sty(fcx: @fn_ctxt,
10-
span: span,
11-
bound_tys: [ty::t],
12-
sty: ty::sty) -> ty::t {
13-
14-
#debug["universally_quantify_from_sty(bound_tys=%?)",
15-
bound_tys.map {|x| fcx.infcx.ty_to_str(x) }];
16-
indent {||
17-
let tcx = fcx.tcx();
18-
let isr = collect_bound_regions_in_tys(tcx, @nil, bound_tys) { |br|
19-
let rvar = fcx.infcx.next_region_var();
20-
#debug["Bound region %s maps to %s",
21-
bound_region_to_str(fcx.ccx.tcx, br),
22-
region_to_str(fcx.ccx.tcx, rvar)];
23-
rvar
24-
};
25-
let t_res = ty::fold_sty_to_ty(fcx.ccx.tcx, sty) { |t|
26-
replace_bound_regions(tcx, span, isr, t)
27-
};
28-
#debug["Result of universal quant. is %s",
29-
fcx.infcx.ty_to_str(t_res)];
30-
t_res
31-
}
5+
fn replace_bound_regions_in_fn_ty(
6+
tcx: ty::ctxt,
7+
isr: isr_alist,
8+
self_ty: option<ty::t>,
9+
fn_ty: ty::fn_ty,
10+
mapf: fn(ty::bound_region) -> ty::region) -> {isr: isr_alist,
11+
self_ty: option<ty::t>,
12+
fn_ty: ty::fn_ty} {
13+
14+
let mut all_tys = ty::tys_in_fn_ty(fn_ty);
15+
for self_ty.each { |t| all_tys += [t] }
16+
17+
#debug["replace_bound_regions_in_fn_ty(self_ty=%?, fn_ty=%s, all_tys=%?)",
18+
self_ty.map { |t| ty_to_str(tcx, t) },
19+
ty_to_str(tcx, ty::mk_fn(tcx, fn_ty)),
20+
all_tys.map { |t| ty_to_str(tcx, t) }];
21+
let _i = indenter();
22+
23+
let isr = collect_bound_regions_in_tys(tcx, isr, all_tys) { |br|
24+
#debug["br=%?", br];
25+
mapf(br)
26+
};
27+
let t_fn = ty::fold_sty_to_ty(tcx, ty::ty_fn(fn_ty)) { |t|
28+
replace_bound_regions(tcx, isr, t)
29+
};
30+
let t_self = self_ty.map { |t| replace_bound_regions(tcx, isr, t) };
31+
32+
#debug["result of replace_bound_regions_in_fn_ty: self_ty=%?, fn_ty=%s",
33+
t_self.map { |t| ty_to_str(tcx, t) },
34+
ty_to_str(tcx, t_fn)];
35+
36+
ret {isr: isr,
37+
self_ty: t_self,
38+
fn_ty: alt check ty::get(t_fn).struct { ty::ty_fn(o) {o} }};
3239
}
3340

3441
// Takes `isr`, a mapping from in-scope region names ("isr"s) to their
@@ -38,7 +45,6 @@ fn universally_quantify_from_sty(fcx: @fn_ctxt,
3845
// with the corresponding bindings in `isr`.
3946
fn replace_bound_regions(
4047
tcx: ty::ctxt,
41-
span: span,
4248
isr: isr_alist,
4349
ty: ty::t) -> ty::t {
4450

@@ -58,8 +64,7 @@ fn replace_bound_regions(
5864
// within that remain bound:
5965
none if in_fn { r }
6066
none {
61-
tcx.sess.span_bug(
62-
span,
67+
tcx.sess.bug(
6368
#fmt["Bound region not found in \
6469
in_scope_regions list: %s",
6570
region_to_str(tcx, r)]);

0 commit comments

Comments
 (0)