Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
1ed6a275
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,发现更多精彩内容 >>
提交
1ed6a275
编写于
12月 28, 2011
作者:
M
Marijn Haverbeke
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Change representation of type params to handle interface bounds
Issue #1227
上级
5930463f
变更
17
隐藏空白更改
内联
并排
Showing
17 changed file
with
317 addition
and
229 deletion
+317
-229
src/comp/metadata/common.rs
src/comp/metadata/common.rs
+1
-1
src/comp/metadata/csearch.rs
src/comp/metadata/csearch.rs
+1
-1
src/comp/metadata/decoder.rs
src/comp/metadata/decoder.rs
+33
-48
src/comp/metadata/encoder.rs
src/comp/metadata/encoder.rs
+22
-24
src/comp/metadata/tydecode.rs
src/comp/metadata/tydecode.rs
+27
-15
src/comp/metadata/tyencode.rs
src/comp/metadata/tyencode.rs
+17
-6
src/comp/middle/kind.rs
src/comp/middle/kind.rs
+3
-1
src/comp/middle/resolve.rs
src/comp/middle/resolve.rs
+4
-3
src/comp/middle/shape.rs
src/comp/middle/shape.rs
+1
-1
src/comp/middle/trans.rs
src/comp/middle/trans.rs
+7
-9
src/comp/middle/ty.rs
src/comp/middle/ty.rs
+38
-13
src/comp/middle/typeck.rs
src/comp/middle/typeck.rs
+98
-69
src/comp/syntax/ast.rs
src/comp/syntax/ast.rs
+8
-2
src/comp/syntax/ast_util.rs
src/comp/syntax/ast_util.rs
+5
-18
src/comp/syntax/parse/parser.rs
src/comp/syntax/parse/parser.rs
+14
-5
src/comp/syntax/print/pprust.rs
src/comp/syntax/print/pprust.rs
+12
-6
src/comp/syntax/visit.rs
src/comp/syntax/visit.rs
+26
-7
未找到文件。
src/comp/metadata/common.rs
浏览文件 @
1ed6a275
...
...
@@ -22,7 +22,7 @@
const
tag_items_data_item_family
:
uint
=
0x0au
;
const
tag_items_data_item_ty_param_
ki
nds
:
uint
=
0x0bu
;
const
tag_items_data_item_ty_param_
bou
nds
:
uint
=
0x0bu
;
const
tag_items_data_item_type
:
uint
=
0x0cu
;
...
...
src/comp/metadata/csearch.rs
浏览文件 @
1ed6a275
...
...
@@ -86,7 +86,7 @@ fn get_impl_methods(cstore: cstore::cstore, def: ast::def_id)
decoder
::
lookup_impl_methods
(
cdata
,
def
.node
,
def
.crate
)
}
fn
get_type
(
tcx
:
ty
::
ctxt
,
def
:
ast
::
def_id
)
->
ty
::
ty_param_
ki
nds_and_ty
{
fn
get_type
(
tcx
:
ty
::
ctxt
,
def
:
ast
::
def_id
)
->
ty
::
ty_param_
bou
nds_and_ty
{
let
cstore
=
tcx
.sess
.get_cstore
();
let
cnum
=
def
.crate
;
let
cdata
=
cstore
::
get_crate_data
(
cstore
,
cnum
)
.data
;
...
...
src/comp/metadata/decoder.rs
浏览文件 @
1ed6a275
...
...
@@ -14,7 +14,6 @@
export
get_tag_variants
;
export
get_type
;
export
get_type_param_count
;
export
get_type_param_kinds
;
export
lookup_def
;
export
lookup_item_name
;
export
resolve_path
;
...
...
@@ -90,21 +89,22 @@ fn variant_tag_id(d: ebml::doc) -> ast::def_id {
ret
parse_def_id
(
ebml
::
doc_data
(
tagdoc
));
}
fn
parse_external_def_id
(
this_cnum
:
ast
::
crate_num
,
extres
:
external_resolver
,
s
:
str
)
->
ast
::
def_id
{
let
buf
=
str
::
bytes
(
s
);
let
external_def_id
=
parse_def_id
(
buf
);
// This item was defined in the crate we're searching if it's has the
// local crate number, otherwise we need to search a different crate
if
external_def_id
.crate
==
ast
::
local_crate
{
ret
{
crate
:
this_cnum
,
node
:
external_def_id
.node
};
}
else
{
ret
extres
(
external_def_id
);
}
}
fn
item_type
(
item
:
ebml
::
doc
,
this_cnum
:
ast
::
crate_num
,
tcx
:
ty
::
ctxt
,
extres
:
external_resolver
)
->
ty
::
t
{
fn
parse_external_def_id
(
this_cnum
:
ast
::
crate_num
,
extres
:
external_resolver
,
s
:
str
)
->
ast
::
def_id
{
let
buf
=
str
::
bytes
(
s
);
let
external_def_id
=
parse_def_id
(
buf
);
// This item was defined in the crate we're searching if it's has the
// local crate number, otherwise we need to search a different crate
if
external_def_id
.crate
==
ast
::
local_crate
{
ret
{
crate
:
this_cnum
,
node
:
external_def_id
.node
};
}
else
{
ret
extres
(
external_def_id
);
}
}
let
tp
=
ebml
::
get_doc
(
item
,
tag_items_data_item_type
);
let
def_parser
=
bind
parse_external_def_id
(
this_cnum
,
extres
,
_
);
let
t
=
parse_ty_data
(
item
.data
,
this_cnum
,
tp
.start
,
tp
.end
-
tp
.start
,
...
...
@@ -115,32 +115,24 @@ fn parse_external_def_id(this_cnum: ast::crate_num,
t
}
fn
item_ty_param_kinds
(
item
:
ebml
::
doc
)
->
[
ast
::
kind
]
{
let
ks
:
[
ast
::
kind
]
=
[];
let
tp
=
tag_items_data_item_ty_param_kinds
;
ebml
::
tagged_docs
(
item
,
tp
)
{|
p
|
let
dat
:
[
u8
]
=
ebml
::
doc_data
(
p
);
let
vi
=
ebml
::
vint_at
(
dat
,
0u
);
let
i
=
0u
;
while
i
<
vi
.val
{
let
k
=
alt
dat
[
vi
.next
+
i
]
as
char
{
's'
{
ast
::
kind_sendable
}
'c'
{
ast
::
kind_copyable
}
'a'
{
ast
::
kind_noncopyable
}
};
ks
+=
[
k
];
i
+=
1u
;
}
};
ret
ks
;
fn
item_ty_param_bounds
(
item
:
ebml
::
doc
,
this_cnum
:
ast
::
crate_num
,
tcx
:
ty
::
ctxt
,
extres
:
external_resolver
)
->
[
@
[
ty
::
param_bound
]]
{
let
bounds
=
[];
let
def_parser
=
bind
parse_external_def_id
(
this_cnum
,
extres
,
_
);
ebml
::
tagged_docs
(
item
,
tag_items_data_item_ty_param_bounds
)
{|
p
|
bounds
+=
[
tydecode
::
parse_bounds_data
(
@
ebml
::
doc_data
(
p
),
this_cnum
,
def_parser
,
tcx
)];
}
bounds
}
fn
item_ty_param_count
(
item
:
ebml
::
doc
)
->
uint
{
let
n
=
0u
;
let
tp
=
tag_items_data_item_ty_param_kinds
;
ebml
::
tagged_docs
(
item
,
tp
)
{|
p
|
n
+=
ebml
::
vint_at
(
ebml
::
doc_data
(
p
),
0u
)
.val
;
ebml
::
tagged_docs
(
item
,
tag_items_data_item_ty_param_bounds
)
{|
p
|
for
byte
in
ebml
::
doc_data
(
p
)
{
if
byte
as
char
==
'.'
{
n
+=
1u
;
}
}
}
n
}
...
...
@@ -213,28 +205,21 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) ->
}
fn
get_type
(
data
:
@
[
u8
],
def
:
ast
::
def_id
,
tcx
:
ty
::
ctxt
,
extres
:
external_resolver
)
->
ty
::
ty_param_
ki
nds_and_ty
{
extres
:
external_resolver
)
->
ty
::
ty_param_
bou
nds_and_ty
{
let
this_cnum
=
def
.crate
;
let
node_id
=
def
.node
;
let
item
=
lookup_item
(
node_id
,
data
);
let
t
=
item_type
(
item
,
this_cnum
,
tcx
,
extres
);
let
tp_kinds
:
[
ast
::
kind
];
let
fam_ch
=
item_family
(
item
);
let
has_ty_params
=
family_has_type_params
(
fam_ch
);
if
has_ty_params
{
tp_kinds
=
item_ty_param_kinds
(
item
);
}
else
{
tp_kinds
=
[];
}
ret
{
kinds
:
tp_kinds
,
ty
:
t
};
let
tp_bounds
=
if
family_has_type_params
(
item_family
(
item
))
{
item_ty_param_bounds
(
item
,
this_cnum
,
tcx
,
extres
)
}
else
{
[]
};
ret
{
bounds
:
tp_bounds
,
ty
:
t
};
}
fn
get_type_param_count
(
data
:
@
[
u8
],
id
:
ast
::
node_id
)
->
uint
{
item_ty_param_count
(
lookup_item
(
id
,
data
))
}
fn
get_type_param_kinds
(
data
:
@
[
u8
],
id
:
ast
::
node_id
)
->
[
ast
::
kind
]
{
ret
item_ty_param_kinds
(
lookup_item
(
id
,
data
));
}
fn
get_symbol
(
data
:
@
[
u8
],
id
:
ast
::
node_id
)
->
str
{
ret
item_symbol
(
lookup_item
(
id
,
data
));
}
...
...
src/comp/metadata/encoder.rs
浏览文件 @
1ed6a275
...
...
@@ -183,18 +183,17 @@ fn encode_family(ebml_w: ebml::writer, c: u8) {
fn
def_to_str
(
did
:
def_id
)
->
str
{
ret
#
fmt
[
"%d:%d"
,
did
.crate
,
did
.node
];
}
fn
encode_type_param_
kinds
(
ebml_w
:
ebml
::
writer
,
tps
:
[
ty_param
])
{
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item_ty_param_kinds
);
ebml
::
write_vint
(
ebml_w
.writer
,
vec
::
len
::
<
ty_param
>
(
tps
));
for
tp
:
ty_param
in
tps
{
let
c
=
alt
ast_util
::
ty_param_kind
(
tp
)
{
kind_sendable
.
{
's'
}
kind_copyable
.
{
'c'
}
kind_noncopyable
.
{
'a'
}
}
;
ebml
_w
.writer
.write
([
c
as
u8
]
);
fn
encode_type_param_
bounds
(
ebml_w
:
ebml
::
writer
,
ecx
:
@
encode_ctxt
,
params
:
[
ty_param
])
{
let
ty_str_ctxt
=
@
{
ds
:
def_to_str
,
tcx
:
ecx
.ccx.tcx
,
abbrevs
:
tyencode
::
ac_use_abbrevs
(
ecx
.type_abbrevs
)};
for
param
in
params
{
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item_ty_param_bounds
);
let
bs
=
ecx
.ccx.tcx.ty_param_bounds
.get
(
local_def
(
param
.id
));
tyencode
::
enc_bounds
(
io
::
new_writer
(
ebml_w
.writer
),
ty_str_ctxt
,
bs
)
;
ebml
::
end_tag
(
ebml_w
);
}
ebml
::
end_tag
(
ebml_w
);
}
fn
encode_variant_id
(
ebml_w
:
ebml
::
writer
,
vid
:
def_id
)
{
...
...
@@ -205,9 +204,8 @@ fn encode_variant_id(ebml_w: ebml::writer, vid: def_id) {
fn
encode_type
(
ecx
:
@
encode_ctxt
,
ebml_w
:
ebml
::
writer
,
typ
:
ty
::
t
)
{
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item_type
);
let
f
=
def_to_str
;
let
ty_str_ctxt
=
@
{
ds
:
f
,
@
{
ds
:
def_to_str
,
tcx
:
ecx
.ccx.tcx
,
abbrevs
:
tyencode
::
ac_use_abbrevs
(
ecx
.type_abbrevs
)};
tyencode
::
enc_ty
(
io
::
new_writer
(
ebml_w
.writer
),
ty_str_ctxt
,
typ
);
...
...
@@ -247,7 +245,7 @@ fn encode_tag_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
encode_symbol
(
ecx
,
ebml_w
,
variant
.node.id
);
}
encode_discriminant
(
ecx
,
ebml_w
,
variant
.node.id
);
encode_type_param_
kinds
(
ebml_w
,
ty_params
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
ty_params
);
ebml
::
end_tag
(
ebml_w
);
}
}
...
...
@@ -293,7 +291,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
pure_fn
.
{
'p'
}
impure_fn
.
{
'f'
}
}
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
node_id_to_monotype
(
ecx
.ccx.tcx
,
item
.id
));
encode_symbol
(
ecx
,
ebml_w
,
item
.id
);
ebml
::
end_tag
(
ebml_w
);
...
...
@@ -312,7 +310,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item
);
encode_def_id
(
ebml_w
,
local_def
(
item
.id
));
encode_family
(
ebml_w
,
'y'
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
node_id_to_monotype
(
ecx
.ccx.tcx
,
item
.id
));
encode_name
(
ebml_w
,
item
.ident
);
ebml
::
end_tag
(
ebml_w
);
...
...
@@ -321,7 +319,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item
);
encode_def_id
(
ebml_w
,
local_def
(
item
.id
));
encode_family
(
ebml_w
,
't'
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
node_id_to_monotype
(
ecx
.ccx.tcx
,
item
.id
));
encode_name
(
ebml_w
,
item
.ident
);
for
v
:
variant
in
variants
{
...
...
@@ -336,7 +334,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item
);
encode_def_id
(
ebml_w
,
local_def
(
ctor_id
));
encode_family
(
ebml_w
,
'y'
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
ty
::
ty_fn_ret
(
ecx
.ccx.tcx
,
fn_ty
));
encode_name
(
ebml_w
,
item
.ident
);
encode_symbol
(
ecx
,
ebml_w
,
item
.id
);
...
...
@@ -346,7 +344,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item
);
encode_def_id
(
ebml_w
,
local_def
(
ctor_id
));
encode_family
(
ebml_w
,
'f'
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
fn_ty
);
encode_symbol
(
ecx
,
ebml_w
,
ctor_id
);
ebml
::
end_tag
(
ebml_w
);
...
...
@@ -357,7 +355,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item
);
encode_def_id
(
ebml_w
,
local_def
(
item
.id
));
encode_family
(
ebml_w
,
'y'
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
ty
::
ty_fn_ret
(
ecx
.ccx.tcx
,
fn_ty
));
encode_name
(
ebml_w
,
item
.ident
);
ebml
::
end_tag
(
ebml_w
);
...
...
@@ -366,7 +364,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item
);
encode_def_id
(
ebml_w
,
local_def
(
ctor_id
));
encode_family
(
ebml_w
,
'f'
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
fn_ty
);
encode_symbol
(
ecx
,
ebml_w
,
ctor_id
);
ebml
::
end_tag
(
ebml_w
);
...
...
@@ -375,7 +373,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item
);
encode_def_id
(
ebml_w
,
local_def
(
item
.id
));
encode_family
(
ebml_w
,
'i'
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
node_id_to_monotype
(
ecx
.ccx.tcx
,
item
.id
));
encode_name
(
ebml_w
,
item
.ident
);
for
m
in
methods
{
...
...
@@ -390,7 +388,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
ebml
::
start_tag
(
ebml_w
,
tag_items_data_item
);
encode_def_id
(
ebml_w
,
local_def
(
m
.id
));
encode_family
(
ebml_w
,
'f'
as
u8
);
encode_type_param_
kinds
(
ebml_w
,
tps
+
m
.tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
+
m
.tps
);
encode_type
(
ecx
,
ebml_w
,
node_id_to_monotype
(
ecx
.ccx.tcx
,
m
.id
));
encode_name
(
ebml_w
,
m
.ident
);
...
...
@@ -421,7 +419,7 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
}
as
u8
;
encode_def_id
(
ebml_w
,
local_def
(
nitem
.id
));
encode_family
(
ebml_w
,
letter
);
encode_type_param_
kinds
(
ebml_w
,
tps
);
encode_type_param_
bounds
(
ebml_w
,
ecx
,
tps
);
encode_type
(
ecx
,
ebml_w
,
node_id_to_monotype
(
ecx
.ccx.tcx
,
nitem
.id
));
encode_symbol
(
ecx
,
ebml_w
,
nitem
.id
);
}
...
...
src/comp/metadata/tydecode.rs
浏览文件 @
1ed6a275
...
...
@@ -10,6 +10,7 @@
export
parse_def_id
;
export
parse_ty_data
;
export
parse_bounds_data
;
// Compact string representation for ty::t values. API ty_str &
// parse_from_str. Extra parameters are for converting to/from def_ids in the
...
...
@@ -21,7 +22,9 @@
type
pstate
=
{
data
:
@
[
u8
],
crate
:
int
,
mutable
pos
:
uint
,
len
:
uint
,
tcx
:
ty
::
ctxt
};
fn
peek
(
st
:
@
pstate
)
->
u8
{
ret
st
.data
[
st
.pos
];
}
fn
peek
(
st
:
@
pstate
)
->
u8
{
if
st
.pos
<
vec
::
len
(
*
st
.data
)
{
st
.data
[
st
.pos
]
}
else
{
0u8
}
}
fn
next
(
st
:
@
pstate
)
->
u8
{
let
ch
=
st
.data
[
st
.pos
];
...
...
@@ -48,8 +51,7 @@ fn parse_ty_data(data: @[u8], crate_num: int, pos: uint, len: uint,
sd
:
str_def
,
tcx
:
ty
::
ctxt
)
->
ty
::
t
{
let
st
=
@
{
data
:
data
,
crate
:
crate_num
,
mutable
pos
:
pos
,
len
:
len
,
tcx
:
tcx
};
let
result
=
parse_ty
(
st
,
sd
);
ret
result
;
parse_ty
(
st
,
sd
)
}
fn
parse_ret_ty
(
st
:
@
pstate
,
sd
:
str_def
)
->
(
ast
::
ret_style
,
ty
::
t
)
{
...
...
@@ -201,18 +203,8 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
ret
ty
::
mk_tag
(
st
.tcx
,
def
,
params
);
}
'p'
{
let
k
=
alt
next
(
st
)
as
char
{
's'
{
kind_sendable
}
'c'
{
kind_copyable
}
'a'
{
kind_noncopyable
}
c
{
#
error
(
"unexpected char in encoded type param: "
);
log
(
error
,
c
);
fail
}
};
ret
ty
::
mk_param
(
st
.tcx
,
parse_int
(
st
)
as
uint
,
k
);
let
bounds
=
parse_bounds
(
st
,
sd
);
ret
ty
::
mk_param
(
st
.tcx
,
parse_int
(
st
)
as
uint
,
bounds
);
}
'@'
{
ret
ty
::
mk_box
(
st
.tcx
,
parse_mt
(
st
,
sd
));
}
'~'
{
ret
ty
::
mk_uniq
(
st
.tcx
,
parse_mt
(
st
,
sd
));
}
...
...
@@ -400,6 +392,26 @@ fn parse_def_id(buf: [u8]) -> ast::def_id {
ret
{
crate
:
crate_num
,
node
:
def_num
};
}
fn
parse_bounds_data
(
data
:
@
[
u8
],
crate_num
:
int
,
sd
:
str_def
,
tcx
:
ty
::
ctxt
)
->
@
[
ty
::
param_bound
]
{
let
st
=
@
{
data
:
data
,
crate
:
crate_num
,
mutable
pos
:
0u
,
len
:
vec
::
len
(
*
data
),
tcx
:
tcx
};
parse_bounds
(
st
,
sd
)
}
fn
parse_bounds
(
st
:
@
pstate
,
sd
:
str_def
)
->
@
[
ty
::
param_bound
]
{
let
bounds
=
[];
while
peek
(
st
)
as
char
==
'.'
{
next
(
st
);
bounds
+=
[
alt
next
(
st
)
as
char
{
'S'
{
ty
::
bound_send
}
'C'
{
ty
::
bound_copy
}
'I'
{
ty
::
bound_iface
(
parse_ty
(
st
,
sd
))
}
}];
}
@
bounds
}
//
// Local Variables:
// mode: rust
...
...
src/comp/metadata/tyencode.rs
浏览文件 @
1ed6a275
...
...
@@ -13,6 +13,7 @@
export
ac_no_abbrevs
;
export
ac_use_abbrevs
;
export
enc_ty
;
export
enc_bounds
;
type
ctxt
=
// Def -> str Callback:
...
...
@@ -175,12 +176,9 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
w
.write_str
(
cx
.ds
(
def
));
w
.write_char
(
'|'
);
}
ty
::
ty_param
(
id
,
k
)
{
alt
k
{
kind_sendable
.
{
w
.write_str
(
"ps"
);
}
kind_copyable
.
{
w
.write_str
(
"pc"
);
}
kind_noncopyable
.
{
w
.write_str
(
"pa"
);
}
}
ty
::
ty_param
(
id
,
bounds
)
{
w
.write_char
(
'p'
);
enc_bounds
(
w
,
cx
,
bounds
);
w
.write_str
(
uint
::
str
(
id
));
}
ty
::
ty_type
.
{
w
.write_char
(
'Y'
);
}
...
...
@@ -265,6 +263,19 @@ fn enc_ty_constr(w: io::writer, cx: @ctxt, c: @ty::type_constr) {
w
.write_char
(
')'
);
}
fn
enc_bounds
(
w
:
io
::
writer
,
cx
:
@
ctxt
,
bs
:
@
[
ty
::
param_bound
])
{
for
bound
in
*
bs
{
w
.write_char
(
'.'
);
alt
bound
{
ty
::
bound_send
.
{
w
.write_char
(
'S'
);
}
ty
::
bound_copy
.
{
w
.write_char
(
'C'
);
}
ty
::
bound_iface
(
tp
)
{
w
.write_char
(
'I'
);
enc_ty
(
w
,
cx
,
tp
);
}
}
}
}
//
// Local Variables:
...
...
src/comp/middle/kind.rs
浏览文件 @
1ed6a275
...
...
@@ -162,7 +162,9 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
alt
substs
.substs
{
some
(
ts
)
{
let
did
=
ast_util
::
def_id_of_def
(
cx
.tcx.def_map
.get
(
e
.id
));
let
kinds
=
ty
::
lookup_item_type
(
cx
.tcx
,
did
)
.kinds
,
i
=
0u
;
let
kinds
=
vec
::
map
(
ty
::
lookup_item_type
(
cx
.tcx
,
did
)
.bounds
,
{|
bs
|
ty
::
param_bounds_to_kind
(
bs
)});
let
i
=
0u
;
for
ty
in
ts
{
let
kind
=
ty
::
type_kind
(
cx
.tcx
,
ty
);
if
!
ty
::
kind_lteq
(
kinds
[
i
],
kind
)
{
...
...
src/comp/middle/resolve.rs
浏览文件 @
1ed6a275
...
...
@@ -399,6 +399,7 @@ fn visit_item_with_scope(i: @ast::item, sc: scopes, v: vt<scopes>) {
let
sc
=
cons
(
scope_item
(
i
),
@
sc
);
alt
i
.node
{
ast
::
item_impl
(
tps
,
ifce
,
sty
,
methods
)
{
visit
::
visit_ty_params
(
tps
,
sc
,
v
);
alt
ifce
{
some
(
ty
)
{
v
.visit_ty
(
ty
,
sc
,
v
);
}
_
{}
}
v
.visit_ty
(
sty
,
sc
,
v
);
for
m
in
methods
{
...
...
@@ -901,12 +902,12 @@ fn in_scope(e: env, sp: span, name: ident, s: scope, ns: namespace) ->
fn
lookup_in_ty_params
(
name
:
ident
,
ty_params
:
[
ast
::
ty_param
])
->
option
::
t
<
def
>
{
let
i
=
0u
;
let
n
=
0u
;
for
tp
:
ast
::
ty_param
in
ty_params
{
if
str
::
eq
(
tp
.ident
,
name
)
{
ret
some
(
ast
::
def_ty_param
(
i
,
ast_util
::
ty_param_kind
(
tp
)
));
ret
some
(
ast
::
def_ty_param
(
local_def
(
tp
.id
),
n
));
}
i
+=
1u
;
n
+=
1u
;
}
ret
none
::
<
def
>
;
}
...
...
src/comp/middle/shape.rs
浏览文件 @
1ed6a275
...
...
@@ -450,7 +450,7 @@ fn gen_tag_shapes(ccx: @crate_ctxt) -> ValueRef {
let
did
=
ccx
.shape_cx.tag_order
[
i
];
let
variants
=
ty
::
tag_variants
(
ccx
.tcx
,
did
);
let
item_tyt
=
ty
::
lookup_item_type
(
ccx
.tcx
,
did
);
let
ty_param_count
=
vec
::
len
(
item_tyt
.
ki
nds
);
let
ty_param_count
=
vec
::
len
(
item_tyt
.
bou
nds
);
for
v
:
ty
::
variant_info
in
*
variants
{
offsets
+=
[
vec
::
len
(
data
)
as
u16
];
...
...
src/comp/middle/trans.rs
浏览文件 @
1ed6a275
...
...
@@ -227,14 +227,14 @@ fn type_of_tag(cx: @crate_ctxt, sp: span, did: ast::def_id, t: ty::t)
}
}
fn
type_of_ty_param_
ki
nds_and_ty
(
lcx
:
@
local_ctxt
,
sp
:
span
,
tpt
:
ty
::
ty_param_
ki
nds_and_ty
)
->
TypeRef
{
fn
type_of_ty_param_
bou
nds_and_ty
(
lcx
:
@
local_ctxt
,
sp
:
span
,
tpt
:
ty
::
ty_param_
bou
nds_and_ty
)
->
TypeRef
{
let
cx
=
lcx
.ccx
;
let
t
=
tpt
.ty
;
alt
ty
::
struct
(
cx
.tcx
,
t
)
{
ty
::
ty_fn
(
_
)
|
ty
::
ty_native_fn
(
_
,
_
)
{
check
returns_non_ty_var
(
cx
,
t
);
ret
type_of_fn_from_ty
(
cx
,
sp
,
t
,
vec
::
len
(
tpt
.
ki
nds
));
ret
type_of_fn_from_ty
(
cx
,
sp
,
t
,
vec
::
len
(
tpt
.
bou
nds
));
}
_
{
// fall through
...
...
@@ -2599,11 +2599,11 @@ fn lval_no_env(bcx: @block_ctxt, val: ValueRef, kind: lval_kind)
}
fn
trans_external_path
(
cx
:
@
block_ctxt
,
did
:
ast
::
def_id
,
tpt
:
ty
::
ty_param_
ki
nds_and_ty
)
->
ValueRef
{
tpt
:
ty
::
ty_param_
bou
nds_and_ty
)
->
ValueRef
{
let
lcx
=
cx
.fcx.lcx
;
let
name
=
csearch
::
get_symbol
(
lcx
.ccx.sess
.get_cstore
(),
did
);
ret
get_extern_const
(
lcx
.ccx.externs
,
lcx
.ccx.llmod
,
name
,
type_of_ty_param_
ki
nds_and_ty
(
lcx
,
cx
.sp
,
tpt
));
type_of_ty_param_
bou
nds_and_ty
(
lcx
,
cx
.sp
,
tpt
));
}
fn
lval_static_fn
(
bcx
:
@
block_ctxt
,
fn_id
:
ast
::
def_id
,
id
:
ast
::
node_id
)
...
...
@@ -2731,8 +2731,7 @@ fn trans_var(cx: @block_ctxt, sp: span, def: ast::def, id: ast::node_id)
ret
lval_no_env
(
cx
,
ccx
.consts
.get
(
did
.node
),
owned
);
}
else
{
let
tp
=
ty
::
node_id_to_monotype
(
ccx
.tcx
,
id
);
let
k
:
[
ast
::
kind
]
=
[];
let
val
=
trans_external_path
(
cx
,
did
,
{
kinds
:
k
,
ty
:
tp
});
let
val
=
trans_external_path
(
cx
,
did
,
{
bounds
:
[],
ty
:
tp
});
ret
lval_no_env
(
cx
,
load_if_immediate
(
cx
,
val
,
tp
),
owned_imm
);
}
}
...
...
@@ -4657,8 +4656,7 @@ fn trans_tag_variant(cx: @local_ctxt, tag_id: ast::node_id,
let
ty_param_substs
:
[
ty
::
t
]
=
[];
i
=
0u
;
for
tp
:
ast
::
ty_param
in
ty_params
{
ty_param_substs
+=
[
ty
::
mk_param
(
ccx
.tcx
,
i
,
ast_util
::
ty_param_kind
(
tp
))];
ty_param_substs
+=
[
ty
::
mk_param
(
ccx
.tcx
,
i
,
@
[])];
i
+=
1u
;
}
let
arg_tys
=
arg_tys_of_fn
(
ccx
,
variant
.node.id
);
...
...
src/comp/middle/ty.rs
浏览文件 @
1ed6a275
...
...
@@ -106,7 +106,7 @@
export
iface_methods
,
store_iface_methods
;
export
tag_variant_with_id
;
export
ty_param_substs_opt_and_ty
;
export
ty_param_
ki
nds_and_ty
;
export
ty_param_
bou
nds_and_ty
;
export
ty_native_fn
;
export
ty_bool
;
export
ty_bot
;
...
...
@@ -185,6 +185,8 @@
export
closure_block
;
export
closure_shared
;
export
closure_send
;
export
param_bound
,
bound_copy
,
bound_send
,
bound_iface
;
export
param_bounds_to_kind
;
// Data types
...
...
@@ -192,7 +194,7 @@
type
field
=
{
ident
:
ast
::
ident
,
mt
:
mt
};
type
method
=
{
ident
:
ast
::
ident
,
tps
:
[
ast
::
kind
],
fty
:
fn_ty
};
type
method
=
{
ident
:
ast
::
ident
,
tps
:
[
@
[
param_bound
]
],
fty
:
fn_ty
};
type
constr_table
=
hashmap
<
ast
::
node_id
,
[
constr
]
>
;
...
...
@@ -217,7 +219,8 @@
kind_cache
:
hashmap
<
t
,
ast
::
kind
>
,
ast_ty_to_ty_cache
:
hashmap
<@
ast
::
ty
,
option
::
t
<
t
>>
,
tag_var_cache
:
hashmap
<
ast
::
def_id
,
@
[
variant_info
]
>
,
iface_method_cache
:
hashmap
<
def_id
,
@
[
method
]
>
};
iface_method_cache
:
hashmap
<
def_id
,
@
[
method
]
>
,
ty_param_bounds
:
hashmap
<
def_id
,
@
[
param_bound
]
>
};
type
ty_ctxt
=
ctxt
;
...
...
@@ -265,7 +268,7 @@
ty_tup
([
t
]);
ty_var
(
int
);
// type variable
ty_param
(
uint
,
ast
::
kind
);
// fn/tag type param
ty_param
(
uint
,
@
[
param_bound
]
);
// fn/tag type param
ty_type
;
// type_desc*
ty_send_type
;
// type_desc* that has been cloned into exchange heap
...
...
@@ -299,9 +302,29 @@
terr_constr_mismatch
(
@
type_constr
,
@
type_constr
);
}
type
ty_param_kinds_and_ty
=
{
kinds
:
[
ast
::
kind
],
ty
:
t
};
tag
param_bound
{
bound_copy
;
bound_send
;
bound_iface
(
t
);
}
fn
param_bounds_to_kind
(
bounds
:
@
[
param_bound
])
->
ast
::
kind
{
let
kind
=
ast
::
kind_noncopyable
;
for
bound
in
*
bounds
{
alt
bound
{
bound_copy
.
{
if
kind
!=
ast
::
kind_sendable
{
kind
=
ast
::
kind_copyable
;
}
}
bound_send
.
{
kind
=
ast
::
kind_sendable
;
}
_
{}
}
}
kind
}
type
ty_param_bounds_and_ty
=
{
bounds
:
[
@
[
param_bound
]],
ty
:
t
};
type
type_cache
=
hashmap
<
ast
::
def_id
,
ty_param_
ki
nds_and_ty
>
;
type
type_cache
=
hashmap
<
ast
::
def_id
,
ty_param_
bou
nds_and_ty
>
;
const
idx_nil
:
uint
=
0u
;
...
...
@@ -415,7 +438,8 @@ fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool {
ast_ty_to_ty_cache
:
map
::
mk_hashmap
(
ast_util
::
hash_ty
,
ast_util
::
eq_ty
),
tag_var_cache
:
new_def_hash
(),
iface_method_cache
:
new_def_hash
()};
iface_method_cache
:
new_def_hash
(),
ty_param_bounds
:
new_def_hash
()};
populate_type_store
(
cx
);
ret
cx
;
}
...
...
@@ -600,7 +624,7 @@ fn mk_res(cx: ctxt, did: ast::def_id, inner: t, tps: [t]) -> t {
fn
mk_var
(
cx
:
ctxt
,
v
:
int
)
->
t
{
ret
gen_ty
(
cx
,
ty_var
(
v
));
}
fn
mk_param
(
cx
:
ctxt
,
n
:
uint
,
k
:
ast
::
kind
)
->
t
{
fn
mk_param
(
cx
:
ctxt
,
n
:
uint
,
k
:
@
[
param_bound
]
)
->
t
{
ret
gen_ty
(
cx
,
ty_param
(
n
,
k
));
}
...
...
@@ -698,7 +722,7 @@ fn walk_ty(cx: ctxt, walker: ty_walk, ty: t) {
tag
fold_mode
{
fm_var
(
fn
@
(
int
)
->
t
);
fm_param
(
fn
@
(
uint
,
ast
::
kind
)
->
t
);
fm_param
(
fn
@
(
uint
,
@
[
param_bound
]
)
->
t
);
fm_general
(
fn
@
(
t
)
->
t
);
}
...
...
@@ -1029,7 +1053,7 @@ fn type_kind(cx: ctxt, ty: t) -> ast::kind {
}
// Resources are always noncopyable.
ty_res
(
did
,
inner
,
tps
)
{
ast
::
kind_noncopyable
}
ty_param
(
_
,
k
)
{
k
}
ty_param
(
_
,
bounds
)
{
param_bounds_to_kind
(
bounds
)
}
ty_constr
(
t
,
_
)
{
type_kind
(
cx
,
t
)
}
};
...
...
@@ -2574,7 +2598,7 @@ fn bind_params_in_type(sp: span, cx: ctxt, next_ty_var: fn@() -> int, typ: t,
while
i
<
ty_param_count
{
*
param_var_ids
+=
[
next_ty_var
()];
i
+=
1u
;
}
fn
binder
(
sp
:
span
,
cx
:
ctxt
,
param_var_ids
:
@
mutable
[
int
],
_
next_ty_var
:
fn
@
()
->
int
,
index
:
uint
,
_
kind
:
ast
::
kind
)
->
t
{
_
bounds
:
@
[
param_bound
]
)
->
t
{
if
index
<
vec
::
len
(
*
param_var_ids
)
{
ret
mk_var
(
cx
,
param_var_ids
[
index
]);
}
else
{
...
...
@@ -2593,7 +2617,8 @@ fn binder(sp: span, cx: ctxt, param_var_ids: @mutable [int],
// substitions.
fn
substitute_type_params
(
cx
:
ctxt
,
substs
:
[
ty
::
t
],
typ
:
t
)
->
t
{
if
!
type_contains_params
(
cx
,
typ
)
{
ret
typ
;
}
fn
substituter
(
_
cx
:
ctxt
,
substs
:
@
[
ty
::
t
],
idx
:
uint
,
_
kind
:
ast
::
kind
)
fn
substituter
(
_
cx
:
ctxt
,
substs
:
@
[
ty
::
t
],
idx
:
uint
,
_
bounds
:
@
[
param_bound
])
->
t
{
// FIXME: bounds check can fail
ret
substs
[
idx
];
...
...
@@ -2674,7 +2699,7 @@ fn tag_variant_with_id(cx: ctxt, tag_id: ast::def_id, variant_id: ast::def_id)
// If the given item is in an external crate, looks up its type and adds it to
// the type cache. Returns the type parameters and type.
fn
lookup_item_type
(
cx
:
ctxt
,
did
:
ast
::
def_id
)
->
ty_param_
ki
nds_and_ty
{
fn
lookup_item_type
(
cx
:
ctxt
,
did
:
ast
::
def_id
)
->
ty_param_
bou
nds_and_ty
{
if
did
.crate
==
ast
::
local_crate
{
// The item is in this crate. The caller should have added it to the
// type cache already; we simply return it.
...
...
src/comp/middle/typeck.rs
浏览文件 @
1ed6a275
import
syntax
::{
ast
,
ast_util
};
import
ast
::
spanned
;
import
syntax
::
ast_util
::{
local_def
,
respan
,
ty_param_kind
};
import
syntax
::
ast_util
::{
local_def
,
respan
};
import
syntax
::
visit
;
import
metadata
::
csearch
;
import
driver
::
session
;
...
...
@@ -9,7 +9,7 @@
import
middle
::
ty
;
import
middle
::
ty
::{
node_id_to_type
,
arg
,
bind_params_in_type
,
block_ty
,
expr_ty
,
field
,
node_type_table
,
mk_nil
,
ty_param_substs_opt_and_ty
,
ty_param_
ki
nds_and_ty
};
ty_param_substs_opt_and_ty
,
ty_param_
bou
nds_and_ty
};
import
util
::
ppaux
::
ty_to_str
;
import
middle
::
ty
::
unify
::{
ures_ok
,
ures_err
,
fix_ok
,
fix_err
};
import
core
::{
int
,
vec
,
str
,
option
};
...
...
@@ -70,28 +70,28 @@ fn lookup_def(fcx: @fn_ctxt, sp: span, id: ast::node_id) -> ast::def {
}
// Returns the type parameter count and the type for the given definition.
fn
ty_param_
ki
nds_and_ty_for_def
(
fcx
:
@
fn_ctxt
,
sp
:
span
,
defn
:
ast
::
def
)
->
ty_param_
ki
nds_and_ty
{
fn
ty_param_
bou
nds_and_ty_for_def
(
fcx
:
@
fn_ctxt
,
sp
:
span
,
defn
:
ast
::
def
)
->
ty_param_
bou
nds_and_ty
{
alt
defn
{
ast
::
def_arg
(
id
,
_
)
{
assert
(
fcx
.locals
.contains_key
(
id
.node
));
let
typ
=
ty
::
mk_var
(
fcx
.ccx.tcx
,
lookup_local
(
fcx
,
sp
,
id
.node
));
ret
{
ki
nds
:
[],
ty
:
typ
};
ret
{
bou
nds
:
[],
ty
:
typ
};
}
ast
::
def_local
(
id
,
_
)
{
assert
(
fcx
.locals
.contains_key
(
id
.node
));
let
typ
=
ty
::
mk_var
(
fcx
.ccx.tcx
,
lookup_local
(
fcx
,
sp
,
id
.node
));
ret
{
ki
nds
:
[],
ty
:
typ
};
ret
{
bou
nds
:
[],
ty
:
typ
};
}
ast
::
def_obj_field
(
id
,
_
)
{
assert
(
fcx
.locals
.contains_key
(
id
.node
));
let
typ
=
ty
::
mk_var
(
fcx
.ccx.tcx
,
lookup_local
(
fcx
,
sp
,
id
.node
));
ret
{
ki
nds
:
[],
ty
:
typ
};
ret
{
bou
nds
:
[],
ty
:
typ
};
}
ast
::
def_self
(
id
)
{
alt
get_self_info
(
fcx
.ccx
)
{
some
(
self_obj
(
_
,
obj_t
))
|
some
(
self_impl
(
obj_t
))
{
ret
{
ki
nds
:
[],
ty
:
obj_t
};
ret
{
bou
nds
:
[],
ty
:
obj_t
};
}
}
}
...
...
@@ -102,18 +102,18 @@ fn ty_param_kinds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
ast
::
def_binding
(
id
)
{
assert
(
fcx
.locals
.contains_key
(
id
.node
));
let
typ
=
ty
::
mk_var
(
fcx
.ccx.tcx
,
lookup_local
(
fcx
,
sp
,
id
.node
));
ret
{
ki
nds
:
[],
ty
:
typ
};
ret
{
bou
nds
:
[],
ty
:
typ
};
}
ast
::
def_mod
(
_
)
{
// Hopefully part of a path.
// TODO: return a type that's more poisonous, perhaps?
ret
{
ki
nds
:
[],
ty
:
ty
::
mk_nil
(
fcx
.ccx.tcx
)};
ret
{
bou
nds
:
[],
ty
:
ty
::
mk_nil
(
fcx
.ccx.tcx
)};
}
ast
::
def_ty
(
_
)
{
fcx
.ccx.tcx.sess
.span_fatal
(
sp
,
"expected value but found type"
);
}
ast
::
def_upvar
(
_
,
inner
,
_
)
{
ret
ty_param_
ki
nds_and_ty_for_def
(
fcx
,
sp
,
*
inner
);
ret
ty_param_
bou
nds_and_ty_for_def
(
fcx
,
sp
,
*
inner
);
}
_
{
// FIXME: handle other names.
...
...
@@ -126,9 +126,9 @@ fn ty_param_kinds_and_ty_for_def(fcx: @fn_ctxt, sp: span, defn: ast::def) ->
// Instantiates the given path, which must refer to an item with the given
// number of type parameters and type.
fn
instantiate_path
(
fcx
:
@
fn_ctxt
,
pth
:
@
ast
::
path
,
tpt
:
ty_param_
ki
nds_and_ty
,
sp
:
span
)
tpt
:
ty_param_
bou
nds_and_ty
,
sp
:
span
)
->
ty_param_substs_opt_and_ty
{
let
ty_param_count
=
vec
::
len
(
tpt
.
ki
nds
);
let
ty_param_count
=
vec
::
len
(
tpt
.
bou
nds
);
let
bind_result
=
bind_params_in_type
(
sp
,
fcx
.ccx.tcx
,
bind
next_ty_var_id
(
fcx
),
tpt
.ty
,
ty_param_count
);
...
...
@@ -238,7 +238,7 @@ fn default_arg_mode_for_ty(tcx: ty::ctxt, m: ast::mode,
fn
ast_ty_to_ty
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
&&
ast_ty
:
@
ast
::
ty
)
->
ty
::
t
{
fn
getter
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
id
:
ast
::
def_id
)
->
ty
::
ty_param_
ki
nds_and_ty
{
->
ty
::
ty_param_
bou
nds_and_ty
{
alt
mode
{
m_check
.
|
m_check_tyvar
(
_
)
{
ty
::
lookup_item_type
(
tcx
,
id
)
}
m_collect
.
{
...
...
@@ -281,14 +281,14 @@ fn instantiate(tcx: ty::ctxt, sp: span, mode: mode,
// TODO: maybe record cname chains so we can do
// "foo = int" like OCaml?
let
ty_param_
ki
nds_and_ty
=
getter
(
tcx
,
mode
,
id
);
if
vec
::
len
(
ty_param_
kinds_and_ty
.ki
nds
)
==
0u
{
ret
ty_param_
ki
nds_and_ty
.ty
;
let
ty_param_
bou
nds_and_ty
=
getter
(
tcx
,
mode
,
id
);
if
vec
::
len
(
ty_param_
bounds_and_ty
.bou
nds
)
==
0u
{
ret
ty_param_
bou
nds_and_ty
.ty
;
}
// The typedef is type-parametric. Do the type substitution.
let
param_bindings
:
[
ty
::
t
]
=
[];
if
vec
::
len
(
args
)
!=
vec
::
len
(
ty_param_
kinds_and_ty
.ki
nds
)
{
if
vec
::
len
(
args
)
!=
vec
::
len
(
ty_param_
bounds_and_ty
.bou
nds
)
{
tcx
.sess
.span_fatal
(
sp
,
"Wrong number of type arguments for a
\
polymorphic type"
);
}
...
...
@@ -297,7 +297,7 @@ fn instantiate(tcx: ty::ctxt, sp: span, mode: mode,
}
let
typ
=
ty
::
substitute_type_params
(
tcx
,
param_bindings
,
ty_param_
ki
nds_and_ty
.ty
);
ty_param_
bou
nds_and_ty
.ty
);
ret
typ
;
}
let
typ
;
...
...
@@ -342,7 +342,9 @@ fn instantiate(tcx: ty::ctxt, sp: span, mode: mode,
typ
=
instantiate
(
tcx
,
ast_ty
.span
,
mode
,
id
,
path
.node.types
);
}
some
(
ast
::
def_native_ty
(
id
))
{
typ
=
getter
(
tcx
,
mode
,
id
)
.ty
;
}
some
(
ast
::
def_ty_param
(
id
,
k
))
{
typ
=
ty
::
mk_param
(
tcx
,
id
,
k
);
}
some
(
ast
::
def_ty_param
(
id
,
n
))
{
typ
=
ty
::
mk_param
(
tcx
,
n
,
tcx
.ty_param_bounds
.get
(
id
));
}
some
(
_
)
{
tcx
.sess
.span_fatal
(
ast_ty
.span
,
"found type name used as a variable"
);
...
...
@@ -376,11 +378,11 @@ fn instantiate(tcx: ty::ctxt, sp: span, mode: mode,
}
fn
ty_of_item
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
it
:
@
ast
::
item
)
->
ty
::
ty_param_
ki
nds_and_ty
{
->
ty
::
ty_param_
bou
nds_and_ty
{
alt
it
.node
{
ast
::
item_const
(
t
,
_
)
{
let
typ
=
ast_ty_to_ty
(
tcx
,
mode
,
t
);
let
tpt
=
{
ki
nds
:
[],
ty
:
typ
};
let
tpt
=
{
bou
nds
:
[],
ty
:
typ
};
tcx
.tcache
.insert
(
local_def
(
it
.id
),
tpt
);
ret
tpt
;
}
...
...
@@ -399,34 +401,37 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
}
// Tell ast_ty_to_ty() that we want to perform a recursive
// call to resolve any named types.
let
typ
=
ty
::
mk_named
(
tcx
,
ast_ty_to_ty
(
tcx
,
mode
,
t
),
@
it
.ident
);
let
tpt
=
{
kinds
:
ty_param_kinds
(
tps
),
ty
:
typ
};
let
tpt
=
{
bounds
:
ty_param_bounds
(
tcx
,
mode
,
tps
),
ty
:
ty
::
mk_named
(
tcx
,
ast_ty_to_ty
(
tcx
,
mode
,
t
),
@
it
.ident
)};
tcx
.tcache
.insert
(
local_def
(
it
.id
),
tpt
);
ret
tpt
;
}
ast
::
item_res
(
decl
,
tps
,
_
,
_
,
_
)
{
let
{
bounds
,
params
}
=
mk_ty_params
(
tcx
,
tps
);
let
t_arg
=
ty_of_arg
(
tcx
,
mode
,
decl
.inputs
[
0
]);
let
t
=
ty
::
mk_named
(
tcx
,
ty
::
mk_res
(
tcx
,
local_def
(
it
.id
),
t_arg
.ty
,
mk_ty_params
(
tcx
,
tps
)
),
params
),
@
it
.ident
);
let
t_res
=
{
kinds
:
ty_param_kinds
(
tps
)
,
ty
:
t
};
let
t_res
=
{
bounds
:
bounds
,
ty
:
t
};
tcx
.tcache
.insert
(
local_def
(
it
.id
),
t_res
);
ret
t_res
;
}
ast
::
item_tag
(
_
,
tps
)
{
// Create a new generic polytype.
let
subtys
:
[
ty
::
t
]
=
mk_ty_params
(
tcx
,
tps
);
let
t
=
ty
::
mk_named
(
tcx
,
ty
::
mk_tag
(
tcx
,
local_def
(
it
.id
),
subty
s
),
let
{
bounds
,
params
}
=
mk_ty_params
(
tcx
,
tps
);
let
t
=
ty
::
mk_named
(
tcx
,
ty
::
mk_tag
(
tcx
,
local_def
(
it
.id
),
param
s
),
@
it
.ident
);
let
tpt
=
{
kinds
:
ty_param_kinds
(
tps
)
,
ty
:
t
};
let
tpt
=
{
bounds
:
bounds
,
ty
:
t
};
tcx
.tcache
.insert
(
local_def
(
it
.id
),
tpt
);
ret
tpt
;
}
ast
::
item_iface
(
tps
,
ms
)
{
let
{
bounds
,
params
}
=
mk_ty_params
(
tcx
,
tps
);
let
t
=
ty
::
mk_named
(
tcx
,
ty
::
mk_iface
(
tcx
,
local_def
(
it
.id
),
mk_ty_params
(
tcx
,
tps
)
),
params
),
@
it
.ident
);
let
tpt
=
{
kinds
:
ty_param_kinds
(
tps
)
,
ty
:
t
};
let
tpt
=
{
bounds
:
bounds
,
ty
:
t
};
tcx
.tcache
.insert
(
local_def
(
it
.id
),
tpt
);
ty
::
store_iface_methods
(
tcx
,
it
.id
,
@
vec
::
map
(
ms
,
{|
m
|
ty_of_ty_method
(
tcx
,
m_collect
,
m
)
...
...
@@ -438,7 +443,7 @@ fn ty_of_item(tcx: ty::ctxt, mode: mode, it: @ast::item)
}
}
fn
ty_of_native_item
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
it
:
@
ast
::
native_item
)
->
ty
::
ty_param_
ki
nds_and_ty
{
->
ty
::
ty_param_
bou
nds_and_ty
{
alt
it
.node
{
ast
::
native_item_fn
(
fn_decl
,
params
)
{
ret
ty_of_native_fn_decl
(
tcx
,
mode
,
fn_decl
,
params
,
...
...
@@ -450,7 +455,7 @@ fn ty_of_native_item(tcx: ty::ctxt, mode: mode, it: @ast::native_item)
none
.
{
}
}
let
t
=
ty
::
mk_native
(
tcx
,
ast_util
::
local_def
(
it
.id
));
let
tpt
=
{
ki
nds
:
[],
ty
:
t
};
let
tpt
=
{
bou
nds
:
[],
ty
:
t
};
tcx
.tcache
.insert
(
local_def
(
it
.id
),
tpt
);
ret
tpt
;
}
...
...
@@ -474,43 +479,69 @@ fn ty_of_fn_decl(tcx: ty::ctxt, mode: mode, decl: ast::fn_decl) -> ty::fn_ty {
}
fn
ty_of_fn
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
decl
:
ast
::
fn_decl
,
ty_params
:
[
ast
::
ty_param
],
def_id
:
ast
::
def_id
)
->
ty
::
ty_param_
ki
nds_and_ty
{
let
tpt
=
{
kinds
:
ty_param_kinds
(
ty_params
),
->
ty
::
ty_param_
bou
nds_and_ty
{
let
tpt
=
{
bounds
:
ty_param_bounds
(
tcx
,
mode
,
ty_params
),
ty
:
ty
::
mk_fn
(
tcx
,
ty_of_fn_decl
(
tcx
,
mode
,
decl
))};
tcx
.tcache
.insert
(
def_id
,
tpt
);
ret
tpt
;
}
fn
ty_of_native_fn_decl
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
decl
:
ast
::
fn_decl
,
ty_params
:
[
ast
::
ty_param
],
def_id
:
ast
::
def_id
)
->
ty
::
ty_param_
ki
nds_and_ty
{
let
input_tys
=
[];
->
ty
::
ty_param_
bou
nds_and_ty
{
let
input_tys
=
[]
,
bounds
=
ty_param_bounds
(
tcx
,
mode
,
ty_params
)
;
for
a
:
ast
::
arg
in
decl
.inputs
{
input_tys
+=
[
ty_of_arg
(
tcx
,
mode
,
a
)];
}
let
output_ty
=
ast_ty_to_ty
(
tcx
,
mode
,
decl
.output
);
let
t_fn
=
ty
::
mk_native_fn
(
tcx
,
input_tys
,
output_ty
);
let
tpt
=
{
kinds
:
ty_param_kinds
(
ty_params
)
,
ty
:
t_fn
};
let
tpt
=
{
bounds
:
bounds
,
ty
:
t_fn
};
tcx
.tcache
.insert
(
def_id
,
tpt
);
ret
tpt
;
}
fn
ty_param_bounds
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
params
:
[
ast
::
ty_param
])
->
[
@
[
ty
::
param_bound
]]
{
let
result
=
[];
for
param
in
params
{
result
+=
[
alt
tcx
.ty_param_bounds
.find
(
local_def
(
param
.id
))
{
some
(
bs
)
{
bs
}
none
.
{
let
bounds
=
[];
for
b
in
*
param
.bounds
{
bounds
+=
[
alt
b
{
ast
::
bound_send
.
{
ty
::
bound_send
}
ast
::
bound_copy
.
{
ty
::
bound_copy
}
ast
::
bound_iface
(
ifc
)
{
ty
::
bound_iface
(
ast_ty_to_ty
(
tcx
,
mode
,
ifc
))
}
}];
}
let
boxed
=
@
bounds
;
tcx
.ty_param_bounds
.insert
(
local_def
(
param
.id
),
boxed
);
boxed
}
}];
}
result
}
fn
ty_of_method
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
m
:
@
ast
::
method
)
->
ty
::
method
{
{
ident
:
m
.ident
,
tps
:
vec
::
map
(
m
.tps
,
{|
tp
|
tp
.kind
}
),
{
ident
:
m
.ident
,
tps
:
ty_param_bounds
(
tcx
,
mode
,
m
.tps
),
fty
:
ty_of_fn_decl
(
tcx
,
mode
,
m
.decl
)}
}
fn
ty_of_ty_method
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
m
:
ast
::
ty_method
)
->
ty
::
method
{
{
ident
:
m
.ident
,
tps
:
vec
::
map
(
m
.tps
,
{|
tp
|
tp
.kind
}
),
{
ident
:
m
.ident
,
tps
:
ty_param_bounds
(
tcx
,
mode
,
m
.tps
),
fty
:
ty_of_fn_decl
(
tcx
,
mode
,
m
.decl
)}
}
fn
ty_of_obj
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
id
:
ast
::
ident
,
ob
:
ast
::
_
obj
,
ty_params
:
[
ast
::
ty_param
])
->
ty
::
ty_param_kinds_and_ty
{
ty_params
:
[
ast
::
ty_param
])
->
ty
::
ty_param_bounds_and_ty
{
let
bounds
=
ty_param_bounds
(
tcx
,
mode
,
ty_params
);
let
methods
=
vec
::
map
(
ob
.methods
,
{|
m
|
ty_of_method
(
tcx
,
mode
,
m
)});
let
t_obj
=
ty
::
mk_named
(
tcx
,
ty
::
mk_obj
(
tcx
,
ty
::
sort_methods
(
methods
)),
@
id
);
ret
{
kinds
:
ty_param_kinds
(
ty_params
)
,
ty
:
t_obj
};
ret
{
bounds
:
bounds
,
ty
:
t_obj
};
}
fn
ty_of_obj_ctor
(
tcx
:
ty
::
ctxt
,
mode
:
mode
,
id
:
ast
::
ident
,
ob
:
ast
::
_
obj
,
ctor_id
:
ast
::
node_id
,
ty_params
:
[
ast
::
ty_param
])
->
ty
::
ty_param_
ki
nds_and_ty
{
->
ty
::
ty_param_
bou
nds_and_ty
{
let
t_obj
=
ty_of_obj
(
tcx
,
mode
,
id
,
ob
,
ty_params
);
let
t_inputs
:
[
arg
]
=
[];
for
f
:
ast
::
obj_field
in
ob
.fields
{
...
...
@@ -520,7 +551,7 @@ fn ty_of_obj_ctor(tcx: ty::ctxt, mode: mode, id: ast::ident, ob: ast::_obj,
let
t_fn
=
ty
::
mk_fn
(
tcx
,
{
proto
:
ast
::
proto_shared
(
ast
::
sugar_normal
),
inputs
:
t_inputs
,
output
:
t_obj
.ty
,
ret_style
:
ast
::
return_val
,
constraints
:
[]});
let
tpt
=
{
kinds
:
ty_param_kinds
(
ty_params
),
ty
:
t_fn
};
let
tpt
=
{
bounds
:
ty_param_bounds
(
tcx
,
mode
,
ty_params
),
ty
:
t_fn
};
tcx
.tcache
.insert
(
local_def
(
ctor_id
),
tpt
);
ret
tpt
;
}
...
...
@@ -588,20 +619,15 @@ fn bot_ty(tcx: ty::ctxt, node_id: ast::node_id) {
}
}
fn
mk_ty_params
(
tcx
:
ty
::
ctxt
,
atps
:
[
ast
::
ty_param
])
->
[
ty
::
t
]
{
let
tps
=
[];
let
i
=
0u
;
for
atp
:
ast
::
ty_param
in
atps
{
tps
+=
[
ty
::
mk_param
(
tcx
,
i
,
ty_param_kind
(
atp
))];
i
+=
1u
;
}
ret
tps
;
}
fn
ty_param_kinds
(
tps
:
[
ast
::
ty_param
])
->
[
ast
::
kind
]
{
let
k
:
[
ast
::
kind
]
=
[];
for
p
:
ast
::
ty_param
in
tps
{
k
+=
[
ty_param_kind
(
p
)];
}
ret
k
;
fn
mk_ty_params
(
tcx
:
ty
::
ctxt
,
atps
:
[
ast
::
ty_param
])
->
{
bounds
:
[
@
[
ty
::
param_bound
]],
params
:
[
ty
::
t
]}
{
let
i
=
0u
,
bounds
=
ty_param_bounds
(
tcx
,
m_collect
,
atps
);
{
bounds
:
bounds
,
params
:
vec
::
map
(
atps
,
{|
_
atp
|
let
t
=
ty
::
mk_param
(
tcx
,
i
,
bounds
[
i
]);
i
+=
1u
;
t
})}
}
// Item collection - a pair of bootstrap passes:
...
...
@@ -646,7 +672,8 @@ fn get_tag_variant_types(cx: @ctxt, tag_ty: ty::t,
inputs
:
args
,
output
:
tag_ty
,
ret_style
:
ast
::
return_val
,
constraints
:
[]})
};
let
tpt
=
{
kinds
:
ty_param_kinds
(
ty_params
),
ty
:
result_ty
};
let
tpt
=
{
bounds
:
ty_param_bounds
(
cx
.tcx
,
m_collect
,
ty_params
),
ty
:
result_ty
};
cx
.tcx.tcache
.insert
(
local_def
(
variant
.node.id
),
tpt
);
write
::
ty_only
(
cx
.tcx
,
variant
.node.id
,
result_ty
);
}
...
...
@@ -660,13 +687,14 @@ fn convert(cx: @ctxt, it: @ast::item) {
write
::
ty_only
(
cx
.tcx
,
it
.id
,
tpt
.ty
);
get_tag_variant_types
(
cx
,
tpt
.ty
,
variants
,
ty_params
);
}
ast
::
item_impl
(
_
,
_
,
selfty
,
ms
)
{
ast
::
item_impl
(
tps
,
_
,
selfty
,
ms
)
{
ty_param_bounds
(
cx
.tcx
,
m_collect
,
tps
);
for
m
in
ms
{
let
bounds
=
ty_param_bounds
(
cx
.tcx
,
m_collect
,
m
.tps
);
let
ty
=
ty
::
mk_fn
(
cx
.tcx
,
ty_of_fn_decl
(
cx
.tcx
,
m_collect
,
m
.decl
));
cx
.tcx.tcache
.insert
(
local_def
(
m
.id
),
{
kinds
:
ty_param_kinds
(
m
.tps
),
ty
:
ty
});
cx
.tcx.tcache
.insert
(
local_def
(
m
.id
),
{
bounds
:
bounds
,
ty
:
ty
});
write
::
ty_only
(
cx
.tcx
,
m
.id
,
ty
);
}
write
::
ty_only
(
cx
.tcx
,
it
.id
,
ast_ty_to_ty
(
cx
.tcx
,
m_collect
,
...
...
@@ -705,10 +733,10 @@ fn convert(cx: @ctxt, it: @ast::item) {
}
}
ast
::
item_res
(
decl
,
tps
,
_
,
dtor_id
,
ctor_id
)
{
let
{
bounds
,
params
}
=
mk_ty_params
(
cx
.tcx
,
tps
);
let
t_arg
=
ty_of_arg
(
cx
.tcx
,
m_collect
,
decl
.inputs
[
0
]);
let
t_res
=
ty
::
mk_res
(
cx
.tcx
,
local_def
(
it
.id
),
t_arg
.ty
,
mk_ty_params
(
cx
.tcx
,
tps
));
let
t_res
=
ty
::
mk_res
(
cx
.tcx
,
local_def
(
it
.id
),
t_arg
.ty
,
params
);
let
t_ctor
=
ty
::
mk_fn
(
cx
.tcx
,
{
proto
:
ast
::
proto_shared
(
ast
::
sugar_normal
),
inputs
:
[{
mode
:
ast
::
by_copy
with
t_arg
}],
...
...
@@ -723,7 +751,8 @@ fn convert(cx: @ctxt, it: @ast::item) {
write
::
ty_only
(
cx
.tcx
,
it
.id
,
t_res
);
write
::
ty_only
(
cx
.tcx
,
ctor_id
,
t_ctor
);
cx
.tcx.tcache
.insert
(
local_def
(
ctor_id
),
{
kinds
:
ty_param_kinds
(
tps
),
ty
:
t_ctor
});
{
bounds
:
bounds
,
ty
:
t_ctor
});
write
::
ty_only
(
cx
.tcx
,
dtor_id
,
t_dtor
);
}
_
{
...
...
@@ -1449,7 +1478,7 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
}
}
else
{
let
tpt
=
csearch
::
get_type
(
fcx
.ccx.tcx
,
did
);
(
vec
::
len
(
tpt
.
ki
nds
),
tpt
.ty
)
(
vec
::
len
(
tpt
.
bou
nds
),
tpt
.ty
)
};
let
{
ids
,
ty
:
self_ty
}
=
if
n_tps
>
0u
{
bind_params_in_type
(
ast_util
::
dummy_sp
(),
fcx
.ccx.tcx
,
...
...
@@ -1782,7 +1811,7 @@ fn check_binop_type_compat(fcx: @fn_ctxt, span: span, ty: ty::t,
ast
::
expr_path
(
pth
)
{
let
defn
=
lookup_def
(
fcx
,
pth
.span
,
id
);
let
tpt
=
ty_param_
ki
nds_and_ty_for_def
(
fcx
,
expr
.span
,
defn
);
let
tpt
=
ty_param_
bou
nds_and_ty_for_def
(
fcx
,
expr
.span
,
defn
);
if
ty
::
def_has_ty_params
(
defn
)
{
let
path_tpot
=
instantiate_path
(
fcx
,
pth
,
tpt
,
expr
.span
);
write
::
ty_fixup
(
fcx
,
id
,
path_tpot
);
...
...
src/comp/syntax/ast.rs
浏览文件 @
1ed6a275
...
...
@@ -24,7 +24,13 @@
const
local_crate
:
crate_num
=
0
;
const
crate_node_id
:
node_id
=
0
;
type
ty_param
=
{
ident
:
ident
,
kind
:
kind
};
tag
ty_param_bound
{
bound_copy
;
bound_send
;
bound_iface
(
@
ty
);
}
type
ty_param
=
{
ident
:
ident
,
id
:
node_id
,
bounds
:
@
[
ty_param_bound
]};
tag
def
{
def_fn
(
def_id
,
purity
);
...
...
@@ -37,7 +43,7 @@
def_local
(
def_id
,
let_style
);
def_variant
(
def_id
/* tag */
,
def_id
/* variant */
);
def_ty
(
def_id
);
def_ty_param
(
uint
,
kind
);
def_ty_param
(
def_id
,
uint
);
def_binding
(
def_id
);
def_use
(
def_id
);
def_native_ty
(
def_id
);
...
...
src/comp/syntax/ast_util.rs
浏览文件 @
1ed6a275
...
...
@@ -25,22 +25,11 @@ fn variant_def_ids(d: def) -> {tg: def_id, var: def_id} {
fn
def_id_of_def
(
d
:
def
)
->
def_id
{
alt
d
{
def_fn
(
id
,
_
)
{
ret
id
;
}
def_obj_field
(
id
,
_
)
{
ret
id
;
}
def_self
(
id
)
{
ret
id
;
}
def_mod
(
id
)
{
ret
id
;
}
def_native_mod
(
id
)
{
ret
id
;
}
def_const
(
id
)
{
ret
id
;
}
def_arg
(
id
,
_
)
{
ret
id
;
}
def_local
(
id
,
_
)
{
ret
id
;
}
def_variant
(
_
,
id
)
{
ret
id
;
}
def_ty
(
id
)
{
ret
id
;
}
def_ty_param
(
_
,
_
)
{
fail
;
}
def_binding
(
id
)
{
ret
id
;
}
def_use
(
id
)
{
ret
id
;
}
def_native_ty
(
id
)
{
ret
id
;
}
def_native_fn
(
id
,
_
)
{
ret
id
;
}
def_upvar
(
id
,
_
,
_
)
{
ret
id
;
}
def_fn
(
id
,
_
)
|
def_obj_field
(
id
,
_
)
|
def_self
(
id
)
|
def_mod
(
id
)
|
def_native_mod
(
id
)
|
def_const
(
id
)
|
def_arg
(
id
,
_
)
|
def_local
(
id
,
_
)
|
def_variant
(
_
,
id
)
|
def_ty
(
id
)
|
def_ty_param
(
id
,
_
)
|
def_binding
(
id
)
|
def_use
(
id
)
|
def_native_ty
(
id
)
|
def_native_fn
(
id
,
_
)
|
def_upvar
(
id
,
_
,
_
)
{
id
}
}
}
...
...
@@ -247,8 +236,6 @@ fn ternary_to_if(e: @expr) -> @expr {
}
}
fn
ty_param_kind
(
tp
:
ty_param
)
->
kind
{
tp
.kind
}
// FIXME this doesn't handle big integer/float literals correctly (nor does
// the rest of our literal handling)
tag
const_val
{
...
...
src/comp/syntax/parse/parser.rs
浏览文件 @
1ed6a275
...
...
@@ -1718,10 +1718,18 @@ fn parse_block_tail(p: parser, lo: uint, s: ast::blk_check_mode) -> ast::blk {
}
fn
parse_ty_param
(
p
:
parser
)
->
ast
::
ty_param
{
let
k
=
if
eat_word
(
p
,
"send"
)
{
ast
::
kind_sendable
}
else
if
eat_word
(
p
,
"copy"
)
{
ast
::
kind_copyable
}
else
{
ast
::
kind_noncopyable
};
ret
{
ident
:
parse_ident
(
p
),
kind
:
k
};
let
bounds
=
[];
if
eat_word
(
p
,
"send"
)
{
bounds
+=
[
ast
::
bound_send
];
}
else
if
eat_word
(
p
,
"copy"
)
{
bounds
+=
[
ast
::
bound_copy
];
}
let
ident
=
parse_ident
(
p
);
if
eat
(
p
,
token
::
COLON
)
{
while
p
.peek
()
!=
token
::
COMMA
&&
p
.peek
()
!=
token
::
GT
{
if
eat_word
(
p
,
"send"
)
{
bounds
+=
[
ast
::
bound_send
];
}
else
if
eat_word
(
p
,
"copy"
)
{
bounds
+=
[
ast
::
bound_copy
];
}
else
{
bounds
+=
[
ast
::
bound_iface
(
parse_ty
(
p
,
false
))];
}
}
}
ret
{
ident
:
ident
,
id
:
p
.get_id
(),
bounds
:
@
bounds
};
}
fn
parse_ty_params
(
p
:
parser
)
->
[
ast
::
ty_param
]
{
...
...
@@ -1856,7 +1864,8 @@ fn wrap_path(p: parser, pt: @ast::path) -> @ast::ty {
ast
::
ty_path
(
pt
,
_
)
{
if
vec
::
len
(
pt
.node.idents
)
==
1u
&&
vec
::
len
(
pt
.node.types
)
==
0u
{
ret
{
ident
:
pt
.node.idents
[
0
],
kind
:
ast
::
kind_sendable
};
ret
{
ident
:
pt
.node.idents
[
0
],
id
:
p
.get_id
(),
bounds
:
@
[]};
}
}
_
{}
...
...
src/comp/syntax/print/pprust.rs
浏览文件 @
1ed6a275
...
...
@@ -1204,11 +1204,17 @@ fn print_arg_mode(s: ps, m: ast::mode) {
}
}
fn
print_kind
(
s
:
ps
,
kind
:
ast
::
kind
)
{
alt
kind
{
ast
::
kind_sendable
.
{
word_nbsp
(
s
,
"send"
);
}
ast
::
kind_copyable
.
{
word_nbsp
(
s
,
"copy"
);
}
ast
::
kind_noncopyable
.
{}
fn
print_bounds
(
s
:
ps
,
bounds
:
@
[
ast
::
ty_param_bound
])
{
if
vec
::
len
(
*
bounds
)
>
0u
{
word
(
s
.s
,
":"
);
for
bound
in
*
bounds
{
nbsp
(
s
);
alt
bound
{
ast
::
bound_copy
.
{
word
(
s
.s
,
"copy"
);
}
ast
::
bound_send
.
{
word
(
s
.s
,
"send"
);
}
ast
::
bound_iface
(
t
)
{
print_type
(
s
,
t
);
}
}
}
}
}
...
...
@@ -1216,8 +1222,8 @@ fn print_type_params(s: ps, params: [ast::ty_param]) {
if
vec
::
len
(
params
)
>
0u
{
word
(
s
.s
,
"<"
);
fn
printParam
(
s
:
ps
,
param
:
ast
::
ty_param
)
{
print_kind
(
s
,
param
.kind
);
word
(
s
.s
,
param
.ident
);
print_bounds
(
s
,
param
.bounds
);
}
commasep
(
s
,
inconsistent
,
params
,
printParam
);
word
(
s
.s
,
">"
);
...
...
src/comp/syntax/visit.rs
浏览文件 @
1ed6a275
...
...
@@ -92,24 +92,27 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
for
vi
:
@
view_item
in
nm
.view_items
{
v
.visit_view_item
(
vi
,
e
,
v
);
}
for
ni
:
@
native_item
in
nm
.items
{
v
.visit_native_item
(
ni
,
e
,
v
);
}
}
item_ty
(
t
,
_
)
{
v
.visit_ty
(
t
,
e
,
v
);
}
item_ty
(
t
,
tps
)
{
v
.visit_ty
(
t
,
e
,
v
);
visit_ty_params
(
tps
,
e
,
v
);
}
item_res
(
decl
,
tps
,
body
,
dtor_id
,
_
)
{
v
.visit_fn
(
decl
,
tps
,
body
,
i
.span
,
some
(
i
.ident
),
dtor_id
,
e
,
v
);
}
item_tag
(
variants
,
_
)
{
item_tag
(
variants
,
tps
)
{
visit_ty_params
(
tps
,
e
,
v
);
for
vr
:
variant
in
variants
{
for
va
:
variant_arg
in
vr
.node.args
{
v
.visit_ty
(
va
.ty
,
e
,
v
);
}
}
}
item_obj
(
ob
,
_
,
_
)
{
item_obj
(
ob
,
tps
,
_
)
{
visit_ty_params
(
tps
,
e
,
v
);
for
f
:
obj_field
in
ob
.fields
{
v
.visit_ty
(
f
.ty
,
e
,
v
);
}
for
m
:
@
method
in
ob
.methods
{
v
.visit_fn
(
m
.decl
,
m
.tps
,
m
.body
,
m
.span
,
some
(
m
.ident
),
m
.id
,
e
,
v
);
}
}
item_impl
(
_
,
ifce
,
ty
,
methods
)
{
item_impl
(
tps
,
ifce
,
ty
,
methods
)
{
visit_ty_params
(
tps
,
e
,
v
);
alt
ifce
{
some
(
ty
)
{
v
.visit_ty
(
ty
,
e
,
v
);
}
_
{}
}
v
.visit_ty
(
ty
,
e
,
v
);
for
m
in
methods
{
...
...
@@ -117,7 +120,8 @@ fn visit_item<E>(i: @item, e: E, v: vt<E>) {
some
(
m
.ident
),
m
.id
,
e
,
v
);
}
}
item_iface
(
_
,
methods
)
{
item_iface
(
tps
,
methods
)
{
visit_ty_params
(
tps
,
e
,
v
);
for
m
in
methods
{
for
a
in
m
.decl.inputs
{
v
.visit_ty
(
a
.ty
,
e
,
v
);
}
v
.visit_ty
(
m
.decl.output
,
e
,
v
);
...
...
@@ -191,11 +195,25 @@ fn visit_pat<E>(p: @pat, e: E, v: vt<E>) {
fn
visit_native_item
<
E
>
(
ni
:
@
native_item
,
e
:
E
,
v
:
vt
<
E
>
)
{
alt
ni
.node
{
native_item_fn
(
fd
,
_
)
{
visit_fn_decl
(
fd
,
e
,
v
);
}
native_item_fn
(
fd
,
tps
)
{
visit_ty_params
(
tps
,
e
,
v
);
visit_fn_decl
(
fd
,
e
,
v
);
}
native_item_ty
.
{
}
}
}
fn
visit_ty_params
<
E
>
(
tps
:
[
ty_param
],
e
:
E
,
v
:
vt
<
E
>
)
{
for
tp
in
tps
{
for
bound
in
*
tp
.bounds
{
alt
bound
{
bound_iface
(
t
)
{
v
.visit_ty
(
t
,
e
,
v
);
}
_
{}
}
}
}
}
fn
visit_fn_decl
<
E
>
(
fd
:
fn_decl
,
e
:
E
,
v
:
vt
<
E
>
)
{
for
a
:
arg
in
fd
.inputs
{
v
.visit_ty
(
a
.ty
,
e
,
v
);
}
for
c
:
@
constr
in
fd
.constraints
{
...
...
@@ -204,9 +222,10 @@ fn visit_fn_decl<E>(fd: fn_decl, e: E, v: vt<E>) {
v
.visit_ty
(
fd
.output
,
e
,
v
);
}
fn
visit_fn
<
E
>
(
decl
:
fn_decl
,
_
tp
:
[
ty_param
],
body
:
blk
,
_
sp
:
span
,
fn
visit_fn
<
E
>
(
decl
:
fn_decl
,
tp
:
[
ty_param
],
body
:
blk
,
_
sp
:
span
,
_
i
:
fn_ident
,
_
id
:
node_id
,
e
:
E
,
v
:
vt
<
E
>
)
{
visit_fn_decl
(
decl
,
e
,
v
);
visit_ty_params
(
tp
,
e
,
v
);
v
.visit_block
(
body
,
e
,
v
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录