Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
60f47eab
R
Rust
项目概览
int
/
Rust
接近 1 年 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rust
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
60f47eab
编写于
8月 06, 2012
作者:
P
Patrick Walton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
rustc: Parse and stub (broken) typechecking for bounded function types
上级
c0f7ed68
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
117 addition
and
70 deletion
+117
-70
src/libsyntax/ast.rs
src/libsyntax/ast.rs
+1
-1
src/libsyntax/ext/auto_serialize.rs
src/libsyntax/ext/auto_serialize.rs
+8
-6
src/libsyntax/fold.rs
src/libsyntax/fold.rs
+4
-1
src/libsyntax/parse/parser.rs
src/libsyntax/parse/parser.rs
+23
-14
src/libsyntax/print/pprust.rs
src/libsyntax/print/pprust.rs
+5
-3
src/libsyntax/visit.rs
src/libsyntax/visit.rs
+12
-7
src/rustc/metadata/tydecode.rs
src/rustc/metadata/tydecode.rs
+3
-2
src/rustc/metadata/tyencode.rs
src/rustc/metadata/tyencode.rs
+1
-0
src/rustc/middle/trans/base.rs
src/rustc/middle/trans/base.rs
+2
-0
src/rustc/middle/trans/foreign.rs
src/rustc/middle/trans/foreign.rs
+1
-0
src/rustc/middle/ty.rs
src/rustc/middle/ty.rs
+3
-1
src/rustc/middle/typeck.rs
src/rustc/middle/typeck.rs
+1
-1
src/rustc/middle/typeck/astconv.rs
src/rustc/middle/typeck/astconv.rs
+6
-3
src/rustc/middle/typeck/check.rs
src/rustc/middle/typeck/check.rs
+3
-1
src/rustc/middle/typeck/collect.rs
src/rustc/middle/typeck/collect.rs
+36
-30
src/rustc/middle/typeck/infer.rs
src/rustc/middle/typeck/infer.rs
+1
-0
src/test/run-pass/bounded-fn-type.rs
src/test/run-pass/bounded-fn-type.rs
+7
-0
未找到文件。
src/libsyntax/ast.rs
浏览文件 @
60f47eab
...
...
@@ -558,7 +558,7 @@ enum ty_ {
ty_ptr
(
mt
),
ty_rptr
(
@
region
,
mt
),
ty_rec
(
~
[
ty_field
]),
ty_fn
(
proto
,
fn_decl
),
ty_fn
(
proto
,
@~
[
ty_param_bound
],
fn_decl
),
ty_tup
(
~
[
@
ty
]),
ty_path
(
@
path
,
node_id
),
ty_fixed_length
(
@
ty
,
option
<
uint
>
),
...
...
src/libsyntax/ext/auto_serialize.rs
浏览文件 @
60f47eab
...
...
@@ -186,10 +186,12 @@ fn ty_fn(span: span,
};
@
{
id
:
self
.next_id
(),
node
:
ast
::
ty_fn
(
ast
::
proto_block
,
{
inputs
:
args
,
output
:
output
,
purity
:
ast
::
impure_fn
,
cf
:
ast
::
return_val
}),
node
:
ast
::
ty_fn
(
ast
::
proto_block
,
@~
[],
{
inputs
:
args
,
output
:
output
,
purity
:
ast
::
impure_fn
,
cf
:
ast
::
return_val
}),
span
:
span
}
}
...
...
@@ -441,7 +443,7 @@ fn ser_ty(cx: ext_ctxt, tps: ser_tps_map,
~
[
#
ast
[
stmt
]{
$
(
s
)
.emit_rec
(
$
(
fld_lambda
));}]
}
ast
::
ty_fn
(
_
,
_
)
=>
{
ast
::
ty_fn
(
*
)
=>
{
cx
.span_err
(
ty
.span
,
~
"cannot serialize function types"
);
~
[]
}
...
...
@@ -681,7 +683,7 @@ fn deser_ty(cx: ext_ctxt, tps: deser_tps_map,
#
ast
{
$
(
d
)
.read_rec
(
$
(
fld_lambda
))
}
}
ast
::
ty_fn
(
_
,
_
)
=>
{
ast
::
ty_fn
(
*
)
=>
{
#
ast
{
fail
}
}
...
...
src/libsyntax/fold.rs
浏览文件 @
60f47eab
...
...
@@ -514,7 +514,10 @@ fn fold_field(f: ty_field, fld: ast_fold) -> ty_field {
ty_ptr
(
mt
)
=>
ty_ptr
(
fold_mt
(
mt
,
fld
)),
ty_rptr
(
region
,
mt
)
=>
ty_rptr
(
region
,
fold_mt
(
mt
,
fld
)),
ty_rec
(
fields
)
=>
ty_rec
(
vec
::
map
(
fields
,
|
f
|
fold_field
(
f
,
fld
))),
ty_fn
(
proto
,
decl
)
=>
ty_fn
(
proto
,
fold_fn_decl
(
decl
,
fld
)),
ty_fn
(
proto
,
bounds
,
decl
)
=>
ty_fn
(
proto
,
@
vec
::
map
(
*
bounds
,
|
x
|
fold_ty_param_bound
(
x
,
fld
)),
fold_fn_decl
(
decl
,
fld
)),
ty_tup
(
tys
)
=>
ty_tup
(
vec
::
map
(
tys
,
|
ty
|
fld
.fold_ty
(
ty
))),
ty_path
(
path
,
id
)
=>
ty_path
(
fld
.fold_path
(
path
),
fld
.new_id
(
id
)),
ty_fixed_length
(
t
,
vs
)
=>
ty_fixed_length
(
fld
.fold_ty
(
t
),
vs
),
...
...
src/libsyntax/parse/parser.rs
浏览文件 @
60f47eab
...
...
@@ -50,10 +50,10 @@
stmt_semi
,
subtract
,
sty_box
,
sty_by_ref
,
sty_region
,
sty_uniq
,
sty_value
,
token_tree
,
trait_method
,
trait_ref
,
tt_delim
,
tt_seq
,
tt_tok
,
tt_nonterminal
,
ty
,
ty_
,
ty_bot
,
ty_box
,
ty_field
,
ty_fn
,
ty_infer
,
ty_mac
,
ty_method
,
ty_nil
,
ty_param
,
ty_pa
th
,
ty_ptr
,
ty_
rec
,
ty_rptr
,
ty_tup
,
ty_u32
,
ty_uniq
,
ty_vec
,
ty_
fixed_length
,
unchecked_blk
,
uniq
,
unsafe_blk
,
unsafe_fn
,
variant
,
view_item
,
view_item_
,
view_item_export
,
ty_infer
,
ty_mac
,
ty_method
,
ty_nil
,
ty_param
,
ty_pa
ram_bound
,
ty_
path
,
ty_ptr
,
ty_rec
,
ty_rptr
,
ty_tup
,
ty_u32
,
ty_uniq
,
ty_
vec
,
ty_fixed_length
,
unchecked_blk
,
uniq
,
unsafe_blk
,
unsafe_fn
,
variant
,
view_item
,
view_item_
,
view_item_export
,
view_item_import
,
view_item_use
,
view_path
,
view_path_glob
,
view_path_list
,
view_path_simple
,
visibility
,
vstore
,
vstore_box
,
vstore_fixed
,
vstore_slice
,
vstore_uniq
};
...
...
@@ -240,14 +240,17 @@ fn warn(m: ~str) {
fn
get_id
()
->
node_id
{
next_node_id
(
self
.sess
)
}
fn
parse_ty_fn
(
purity
:
ast
::
purity
)
->
ty_
{
let
proto
=
if
self
.eat_keyword
(
~
"extern"
)
{
let
proto
,
bounds
;
if
self
.eat_keyword
(
~
"extern"
)
{
self
.expect_keyword
(
~
"fn"
);
ast
::
proto_bare
proto
=
ast
::
proto_bare
;
bounds
=
@~
[];
}
else
{
self
.expect_keyword
(
~
"fn"
);
self
.parse_fn_ty_proto
()
proto
=
self
.parse_fn_ty_proto
();
bounds
=
self
.parse_optional_ty_param_bounds
();
};
ty_fn
(
proto
,
self
.parse_ty_fn_decl
(
purity
))
ty_fn
(
proto
,
bounds
,
self
.parse_ty_fn_decl
(
purity
))
}
fn
parse_ty_fn_decl
(
purity
:
ast
::
purity
)
->
fn_decl
{
...
...
@@ -467,7 +470,7 @@ fn parse_ty(colons_before_params: bool) -> @ty {
self
.parse_ty_fn
(
ast
::
impure_fn
)
}
else
if
self
.eat_keyword
(
~
"extern"
)
{
self
.expect_keyword
(
~
"fn"
);
ty_fn
(
proto_bare
,
self
.parse_ty_fn_decl
(
ast
::
impure_fn
))
ty_fn
(
proto_bare
,
@~
[],
self
.parse_ty_fn_decl
(
ast
::
impure_fn
))
}
else
if
self
.token
==
token
::
MOD_SEP
||
is_ident
(
self
.token
)
{
let
path
=
self
.parse_path_with_tps
(
colons_before_params
);
ty_path
(
path
,
self
.get_id
())
...
...
@@ -2125,11 +2128,10 @@ fn parse_block_tail_(lo: uint, s: blk_check_mode,
return
spanned
(
lo
,
hi
,
bloc
);
}
fn
parse_
ty_param
()
->
ty_param
{
fn
parse_
optional_ty_param_bounds
()
->
@~
[
ty_param_bound
]
{
let
mut
bounds
=
~
[];
let
ident
=
self
.parse_ident
();
if
self
.eat
(
token
::
COLON
)
{
while
self
.token
!=
token
::
COMMA
&&
self
.token
!=
token
::
GT
{
while
is_ident
(
self
.token
)
{
if
self
.eat_keyword
(
~
"send"
)
{
push
(
bounds
,
bound_send
);
}
else
if
self
.eat_keyword
(
~
"copy"
)
{
...
...
@@ -2139,10 +2141,17 @@ fn parse_ty_param() -> ty_param {
}
else
if
self
.eat_keyword
(
~
"owned"
)
{
push
(
bounds
,
bound_owned
);
}
else
{
push
(
bounds
,
bound_trait
(
self
.parse_ty
(
false
)));
}
push
(
bounds
,
bound_trait
(
self
.parse_ty
(
false
)));
}
}
}
return
{
ident
:
ident
,
id
:
self
.get_id
(),
bounds
:
@
bounds
};
return
@
move
bounds
;
}
fn
parse_ty_param
()
->
ty_param
{
let
ident
=
self
.parse_ident
();
let
bounds
=
self
.parse_optional_ty_param_bounds
();
return
{
ident
:
ident
,
id
:
self
.get_id
(),
bounds
:
bounds
};
}
fn
parse_ty_params
()
->
~
[
ty_param
]
{
...
...
src/libsyntax/print/pprust.rs
浏览文件 @
60f47eab
...
...
@@ -399,8 +399,8 @@ fn print_field(s: ps, f: ast::ty_field) {
commasep
(
s
,
inconsistent
,
elts
,
print_type
);
pclose
(
s
);
}
ast
::
ty_fn
(
proto
,
d
)
=>
{
print_ty_fn
(
s
,
some
(
proto
),
d
,
none
,
none
);
ast
::
ty_fn
(
proto
,
bounds
,
d
)
=>
{
print_ty_fn
(
s
,
some
(
proto
),
bounds
,
d
,
none
,
none
);
}
ast
::
ty_path
(
path
,
_
)
=>
print_path
(
s
,
path
,
print_colons
),
ast
::
ty_fixed_length
(
t
,
v
)
=>
{
...
...
@@ -702,7 +702,7 @@ fn print_ty_method(s: ps, m: ast::ty_method) {
hardbreak_if_not_bol
(
s
);
maybe_print_comment
(
s
,
m
.span.lo
);
print_outer_attributes
(
s
,
m
.attrs
);
print_ty_fn
(
s
,
none
,
m
.decl
,
some
(
m
.ident
),
some
(
m
.tps
));
print_ty_fn
(
s
,
none
,
@~
[],
m
.decl
,
some
(
m
.ident
),
some
(
m
.tps
));
word
(
s
.s
,
~
";"
);
}
...
...
@@ -1645,10 +1645,12 @@ fn print_arg(s: ps, input: ast::arg) {
}
fn
print_ty_fn
(
s
:
ps
,
opt_proto
:
option
<
ast
::
proto
>
,
bounds
:
@~
[
ast
::
ty_param_bound
],
decl
:
ast
::
fn_decl
,
id
:
option
<
ast
::
ident
>
,
tps
:
option
<~
[
ast
::
ty_param
]
>
)
{
ibox
(
s
,
indent_unit
);
word
(
s
.s
,
opt_proto_to_str
(
opt_proto
));
print_bounds
(
s
,
bounds
);
match
id
{
some
(
id
)
=>
{
word
(
s
.s
,
~
" "
);
word
(
s
.s
,
*
id
);
}
_
=>
()
}
match
tps
{
some
(
tps
)
=>
print_type_params
(
s
,
tps
),
_
=>
()
}
zerobreak
(
s
.s
);
...
...
src/libsyntax/visit.rs
浏览文件 @
60f47eab
...
...
@@ -195,8 +195,9 @@ fn visit_ty<E>(t: @ty, e: E, v: vt<E>) {
ty_tup
(
ts
)
=>
for
ts
.each
|
tt
|
{
v
.visit_ty
(
tt
,
e
,
v
);
}
ty_fn
(
_
,
decl
)
=>
{
ty_fn
(
_
,
bounds
,
decl
)
=>
{
for
decl
.inputs.each
|
a
|
{
v
.visit_ty
(
a
.ty
,
e
,
v
);
}
visit_ty_param_bounds
(
bounds
,
e
,
v
);
v
.visit_ty
(
decl
.output
,
e
,
v
);
}
ty_path
(
p
,
_
)
=>
visit_path
(
p
,
e
,
v
),
...
...
@@ -251,14 +252,18 @@ fn visit_foreign_item<E>(ni: @foreign_item, e: E, v: vt<E>) {
}
}
fn
visit_ty_param_bounds
<
E
>
(
bounds
:
@~
[
ty_param_bound
],
e
:
E
,
v
:
vt
<
E
>
)
{
for
vec
::
each
(
*
bounds
)
|
bound
|
{
match
bound
{
bound_trait
(
t
)
=>
v
.visit_ty
(
t
,
e
,
v
),
bound_copy
|
bound_send
|
bound_const
|
bound_owned
=>
()
}
}
}
fn
visit_ty_params
<
E
>
(
tps
:
~
[
ty_param
],
e
:
E
,
v
:
vt
<
E
>
)
{
for
tps
.each
|
tp
|
{
for
vec
::
each
(
*
tp
.bounds
)
|
bound
|
{
match
bound
{
bound_trait
(
t
)
=>
v
.visit_ty
(
t
,
e
,
v
),
bound_copy
|
bound_send
|
bound_const
|
bound_owned
=>
()
}
}
visit_ty_param_bounds
(
tp
.bounds
,
e
,
v
);
}
}
...
...
src/rustc/metadata/tydecode.rs
浏览文件 @
60f47eab
...
...
@@ -362,6 +362,7 @@ fn parse_purity(c: char) -> purity {
fn
parse_ty_fn
(
st
:
@
pstate
,
conv
:
conv_did
)
->
ty
::
fn_ty
{
let
proto
=
parse_proto
(
next
(
st
));
let
purity
=
parse_purity
(
next
(
st
));
let
bounds
=
parse_bounds
(
st
,
conv
);
assert
(
next
(
st
)
==
'['
);
let
mut
inputs
:
~
[
ty
::
arg
]
=
~
[];
while
peek
(
st
)
!=
']'
{
...
...
@@ -377,8 +378,8 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty {
}
st
.pos
+=
1u
;
// eat the ']'
let
(
ret_style
,
ret_ty
)
=
parse_ret_ty
(
st
,
conv
);
return
{
purity
:
purity
,
proto
:
proto
,
inputs
:
inputs
,
output
:
ret_ty
,
ret_style
:
ret_style
};
return
{
purity
:
purity
,
proto
:
proto
,
bounds
:
bounds
,
inputs
:
inputs
,
output
:
ret_ty
,
ret_style
:
ret_style
};
}
...
...
src/rustc/metadata/tyencode.rs
浏览文件 @
60f47eab
...
...
@@ -337,6 +337,7 @@ fn enc_purity(w: io::writer, p: purity) {
fn
enc_ty_fn
(
w
:
io
::
writer
,
cx
:
@
ctxt
,
ft
:
ty
::
fn_ty
)
{
enc_proto
(
w
,
ft
.proto
);
enc_purity
(
w
,
ft
.purity
);
enc_bounds
(
w
,
cx
,
ft
.bounds
);
w
.write_char
(
'['
);
for
ft
.inputs.each
|
arg
|
{
enc_mode
(
w
,
cx
,
arg
.mode
);
...
...
src/rustc/middle/trans/base.rs
浏览文件 @
60f47eab
...
...
@@ -1982,6 +1982,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> option<ty::t> {
ty
::
ty_fn
(
fty
)
=>
{
some
(
ty
::
mk_fn
(
tcx
,
{
purity
:
ast
::
impure_fn
,
proto
:
fty
.proto
,
bounds
:
@~
[],
inputs
:
~
[],
output
:
ty
::
mk_nil
(
tcx
),
ret_style
:
ast
::
return_val
}))
...
...
@@ -1989,6 +1990,7 @@ fn normalize_for_monomorphization(tcx: ty::ctxt, ty: ty::t) -> option<ty::t> {
ty
::
ty_trait
(
_
,
_
)
=>
{
some
(
ty
::
mk_fn
(
tcx
,
{
purity
:
ast
::
impure_fn
,
proto
:
ast
::
proto_box
,
bounds
:
@~
[],
inputs
:
~
[],
output
:
ty
::
mk_nil
(
tcx
),
ret_style
:
ast
::
return_val
}))
...
...
src/rustc/middle/trans/foreign.rs
浏览文件 @
60f47eab
...
...
@@ -961,6 +961,7 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
let
fty
=
ty
::
mk_fn
(
bcx
.tcx
(),
{
purity
:
ast
::
impure_fn
,
proto
:
ast
::
proto_block
,
bounds
:
@~
[],
inputs
:
~
[{
mode
:
ast
::
expl
(
ast
::
by_val
),
ty
:
ty
::
mk_imm_ptr
(
...
...
src/rustc/middle/ty.rs
浏览文件 @
60f47eab
...
...
@@ -316,11 +316,13 @@ enum closure_kind {
///
/// - `purity` is the function's effect (pure, impure, unsafe).
/// - `proto` is the protocol (fn@, fn~, etc).
/// - `bound` is the parameter bounds on the function's upvars.
/// - `inputs` is the list of arguments and their modes.
/// - `output` is the return type.
/// - `ret_style`indicates whether the function returns a value or fails.
/// - `ret_style`
indicates whether the function returns a value or fails.
type
fn_ty
=
{
purity
:
ast
::
purity
,
proto
:
ast
::
proto
,
bounds
:
@~
[
param_bound
],
inputs
:
~
[
arg
],
output
:
t
,
ret_style
:
ret_style
};
...
...
src/rustc/middle/typeck.rs
浏览文件 @
60f47eab
...
...
@@ -246,7 +246,7 @@ fn check_main_fn_ty(ccx: @crate_ctxt,
let
tcx
=
ccx
.tcx
;
let
main_t
=
ty
::
node_id_to_type
(
tcx
,
main_id
);
match
ty
::
get
(
main_t
)
.struct
{
ty
::
ty_fn
({
purity
:
ast
::
impure_fn
,
proto
:
ast
::
proto_bare
,
ty
::
ty_fn
({
purity
:
ast
::
impure_fn
,
proto
:
ast
::
proto_bare
,
bounds
,
inputs
,
output
,
ret_style
:
ast
::
return_val
})
=>
{
match
tcx
.items
.find
(
main_id
)
{
some
(
ast_map
::
node_item
(
it
,
_
))
=>
{
...
...
src/rustc/middle/typeck/astconv.rs
浏览文件 @
60f47eab
...
...
@@ -261,8 +261,10 @@ fn check_path_args(tcx: ty::ctxt,
};
ty
::
mk_rec
(
tcx
,
flds
)
}
ast
::
ty_fn
(
proto
,
decl
)
=>
{
ty
::
mk_fn
(
tcx
,
ty_of_fn_decl
(
self
,
rscope
,
proto
,
decl
,
none
))
ast
::
ty_fn
(
proto
,
ast_bounds
,
decl
)
=>
{
let
bounds
=
collect
::
compute_bounds
(
self
.ccx
(),
ast_bounds
);
let
fn_decl
=
ty_of_fn_decl
(
self
,
rscope
,
proto
,
bounds
,
decl
,
none
);
ty
::
mk_fn
(
tcx
,
fn_decl
)
}
ast
::
ty_path
(
path
,
id
)
=>
{
let
a_def
=
match
tcx
.def_map
.find
(
id
)
{
...
...
@@ -398,6 +400,7 @@ fn ty_of_arg<AC: ast_conv, RS: region_scope copy owned>(
fn
ty_of_fn_decl
<
AC
:
ast_conv
,
RS
:
region_scope
copy
owned
>
(
self
:
AC
,
rscope
:
RS
,
proto
:
ast
::
proto
,
bounds
:
@~
[
ty
::
param_bound
],
decl
:
ast
::
fn_decl
,
expected_tys
:
expected_tys
)
->
ty
::
fn_ty
{
...
...
@@ -423,7 +426,7 @@ fn ty_of_fn_decl<AC: ast_conv, RS: region_scope copy owned>(
_
=>
ast_ty_to_ty
(
self
,
rb
,
decl
.output
)
};
{
purity
:
decl
.purity
,
proto
:
proto
,
inputs
:
input_tys
,
{
purity
:
decl
.purity
,
proto
:
proto
,
bounds
:
bounds
,
inputs
:
input_tys
,
output
:
output_ty
,
ret_style
:
decl
.cf
}
}
}
...
...
src/rustc/middle/typeck/check.rs
浏览文件 @
60f47eab
...
...
@@ -1135,7 +1135,7 @@ fn check_expr_fn(fcx: @fn_ctxt,
};
// construct the function type
let
fn_ty
=
astconv
::
ty_of_fn_decl
(
fcx
,
fcx
,
proto
,
let
fn_ty
=
astconv
::
ty_of_fn_decl
(
fcx
,
fcx
,
proto
,
@~
[],
decl
,
expected_tys
);
let
fty
=
ty
::
mk_fn
(
tcx
,
fn_ty
);
...
...
@@ -2401,6 +2401,7 @@ fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
let
fty
=
ty
::
mk_fn
(
ccx
.tcx
,
{
purity
:
ast
::
impure_fn
,
proto
:
ast
::
proto_block
,
bounds
:
@~
[],
inputs
:
~
[{
mode
:
ast
::
expl
(
ast
::
by_val
),
ty
:
ty
::
mk_imm_ptr
(
...
...
@@ -2420,6 +2421,7 @@ fn arg(m: ast::rmode, ty: ty::t) -> ty::arg {
};
let
fty
=
ty
::
mk_fn
(
tcx
,
{
purity
:
ast
::
impure_fn
,
proto
:
ast
::
proto_bare
,
bounds
:
@~
[],
inputs
:
inputs
,
output
:
output
,
ret_style
:
ast
::
return_val
});
let
i_ty
=
ty
::
lookup_item_type
(
ccx
.tcx
,
local_def
(
it
.id
));
...
...
src/rustc/middle/typeck/collect.rs
浏览文件 @
60f47eab
...
...
@@ -125,6 +125,7 @@ fn get_enum_variant_types(ccx: @crate_ctxt,
});
ty
::
mk_fn
(
tcx
,
{
purity
:
ast
::
pure_fn
,
proto
:
ast
::
proto_box
,
bounds
:
@~
[],
inputs
:
args
,
output
:
enum_ty
,
ret_style
:
ast
::
return_val
})
...
...
@@ -396,6 +397,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
let
t_ctor
=
ty
::
mk_fn
(
tcx
,
{
purity
:
ast
::
impure_fn
,
proto
:
ast
::
proto_block
,
bounds
:
@~
[],
inputs
:
t_args
,
output
:
t_res
,
ret_style
:
ast
::
return_val
});
...
...
@@ -410,7 +412,7 @@ fn convert(ccx: @crate_ctxt, it: @ast::item) {
// Write the dtor type
let
t_dtor
=
ty
::
mk_fn
(
tcx
,
ty_of_fn_decl
(
ccx
,
type_rscope
(
rp
),
ast
::
proto_block
,
ty_of_fn_decl
(
ccx
,
type_rscope
(
rp
),
ast
::
proto_block
,
@~
[],
ast_util
::
dtor_dec
(),
none
));
write_ty_to_tcx
(
tcx
,
dtor
.node.id
,
t_dtor
);
tcx
.tcache
.insert
(
local_def
(
dtor
.node.id
),
...
...
@@ -460,9 +462,10 @@ fn convert_foreign(ccx: @crate_ctxt, i: @ast::foreign_item) {
fn
ty_of_method
(
ccx
:
@
crate_ctxt
,
m
:
@
ast
::
method
,
rp
:
bool
)
->
ty
::
method
{
// XXX: Are the bounds correct here?
{
ident
:
m
.ident
,
tps
:
ty_param_bounds
(
ccx
,
m
.tps
),
fty
:
ty_of_fn_decl
(
ccx
,
type_rscope
(
rp
),
ast
::
proto_bare
,
fty
:
ty_of_fn_decl
(
ccx
,
type_rscope
(
rp
),
ast
::
proto_bare
,
@~
[],
m
.decl
,
none
),
self_ty
:
m
.self_ty.node
,
purity
:
m
.decl.purity
,
...
...
@@ -474,8 +477,8 @@ fn ty_of_ty_method(self: @crate_ctxt,
rp
:
bool
)
->
ty
::
method
{
{
ident
:
m
.ident
,
tps
:
ty_param_bounds
(
self
,
m
.tps
),
fty
:
ty_of_fn_decl
(
self
,
type_rscope
(
rp
),
ast
::
proto_bare
,
m
.decl
,
none
),
fty
:
ty_of_fn_decl
(
self
,
type_rscope
(
rp
),
ast
::
proto_bare
,
@~
[],
m
.decl
,
none
),
// assume public, because this is only invoked on trait methods
self_ty
:
m
.self_ty.node
,
purity
:
m
.decl.purity
,
vis
:
ast
::
public
}
...
...
@@ -528,8 +531,8 @@ fn ty_of_item(ccx: @crate_ctxt, it: @ast::item)
}
ast
::
item_fn
(
decl
,
tps
,
_
)
=>
{
let
bounds
=
ty_param_bounds
(
ccx
,
tps
);
let
tofd
=
ty_of_fn_decl
(
ccx
,
empty_rscope
,
ast
::
proto_bare
,
decl
,
none
);
let
tofd
=
ty_of_fn_decl
(
ccx
,
empty_rscope
,
ast
::
proto_bare
,
@~
[],
decl
,
none
);
let
tpt
=
{
bounds
:
bounds
,
rp
:
false
,
// functions do not have a self
ty
:
ty
::
mk_fn
(
ccx
.tcx
,
tofd
)};
...
...
@@ -599,40 +602,42 @@ fn ty_of_foreign_item(ccx: @crate_ctxt, it: @ast::foreign_item)
}
}
}
fn
ty_param_bounds
(
ccx
:
@
crate_ctxt
,
params
:
~
[
ast
::
ty_param
])
->
@~
[
ty
::
param_bounds
]
{
fn
compute_bounds
(
ccx
:
@
crate_ctxt
,
param
:
ast
::
ty_param
)
->
ty
::
param_bounds
{
@
do
vec
::
flat_map
(
*
param
.bounds
)
|
b
|
{
match
b
{
ast
::
bound_send
=>
~
[
ty
::
bound_send
],
ast
::
bound_copy
=>
~
[
ty
::
bound_copy
],
ast
::
bound_const
=>
~
[
ty
::
bound_const
],
ast
::
bound_owned
=>
~
[
ty
::
bound_owned
],
ast
::
bound_trait
(
t
)
=>
{
let
ity
=
ast_ty_to_ty
(
ccx
,
empty_rscope
,
t
);
match
ty
::
get
(
ity
)
.struct
{
ty
::
ty_trait
(
*
)
=>
{
~
[
ty
::
bound_trait
(
ity
)]
}
_
=>
{
ccx
.tcx.sess
.span_err
(
t
.span
,
~
"type parameter bounds must be
\
trait types"
);
~
[]
}
}
fn
compute_bounds
(
ccx
:
@
crate_ctxt
,
ast_bounds
:
@~
[
ast
::
ty_param_bound
])
->
ty
::
param_bounds
{
@
do
vec
::
flat_map
(
*
ast_bounds
)
|
b
|
{
match
b
{
ast
::
bound_send
=>
~
[
ty
::
bound_send
],
ast
::
bound_copy
=>
~
[
ty
::
bound_copy
],
ast
::
bound_const
=>
~
[
ty
::
bound_const
],
ast
::
bound_owned
=>
~
[
ty
::
bound_owned
],
ast
::
bound_trait
(
t
)
=>
{
let
ity
=
ast_ty_to_ty
(
ccx
,
empty_rscope
,
t
);
match
ty
::
get
(
ity
)
.struct
{
ty
::
ty_trait
(
*
)
=>
{
~
[
ty
::
bound_trait
(
ity
)]
}
_
=>
{
ccx
.tcx.sess
.span_err
(
t
.span
,
~
"type parameter bounds must be
\
trait types"
);
~
[]
}
}
}
}
}
}
fn
ty_param_bounds
(
ccx
:
@
crate_ctxt
,
params
:
~
[
ast
::
ty_param
])
->
@~
[
ty
::
param_bounds
]
{
@
do
params
.map
|
param
|
{
match
ccx
.tcx.ty_param_bounds
.find
(
param
.id
)
{
some
(
bs
)
=>
bs
,
none
=>
{
let
bounds
=
compute_bounds
(
ccx
,
param
);
let
bounds
=
compute_bounds
(
ccx
,
param
.bounds
);
ccx
.tcx.ty_param_bounds
.insert
(
param
.id
,
bounds
);
bounds
}
...
...
@@ -652,6 +657,7 @@ fn ty_of_foreign_fn_decl(ccx: @crate_ctxt,
let
t_fn
=
ty
::
mk_fn
(
ccx
.tcx
,
{
purity
:
decl
.purity
,
proto
:
ast
::
proto_bare
,
bounds
:
@~
[],
inputs
:
input_tys
,
output
:
output_ty
,
ret_style
:
ast
::
return_val
});
...
...
src/rustc/middle/typeck/infer.rs
浏览文件 @
60f47eab
...
...
@@ -1717,6 +1717,7 @@ fn argvecs<C:combine>(self: C, a_args: ~[ty::arg],
// b_f.constraints).then {||
ok
({
purity
:
purity
,
proto
:
p
,
bounds
:
a_f
.bounds
,
// XXX: This is wrong!
inputs
:
inputs
,
output
:
output
,
ret_style
:
rs
})
...
...
src/test/run-pass/bounded-fn-type.rs
0 → 100644
浏览文件 @
60f47eab
fn
ignore
<
T
>
(
_
x
:
T
)
{}
fn
main
()
{
let
f
:
fn
@
:
send
()
=
||();
ignore
(
f
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录