Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
088c94ae
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,发现更多精彩内容 >>
提交
088c94ae
编写于
9月 12, 2014
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
trans -- stop tracking vtables precisely, instead recompute as needed.
上级
6349a612
变更
21
展开全部
隐藏空白更改
内联
并排
Showing
21 changed file
with
723 addition
and
544 deletion
+723
-544
src/librustc/lint/builtin.rs
src/librustc/lint/builtin.rs
+5
-5
src/librustc/metadata/common.rs
src/librustc/metadata/common.rs
+2
-1
src/librustc/metadata/encoder.rs
src/librustc/metadata/encoder.rs
+14
-14
src/librustc/middle/astencode.rs
src/librustc/middle/astencode.rs
+180
-60
src/librustc/middle/dead.rs
src/librustc/middle/dead.rs
+5
-5
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/expr_use_visitor.rs
+3
-5
src/librustc/middle/privacy.rs
src/librustc/middle/privacy.rs
+7
-7
src/librustc/middle/save/mod.rs
src/librustc/middle/save/mod.rs
+4
-4
src/librustc/middle/subst.rs
src/librustc/middle/subst.rs
+5
-0
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/base.rs
+1
-3
src/librustc/middle/trans/callee.rs
src/librustc/middle/trans/callee.rs
+29
-82
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/common.rs
+100
-88
src/librustc/middle/trans/context.rs
src/librustc/middle/trans/context.rs
+11
-2
src/librustc/middle/trans/expr.rs
src/librustc/middle/trans/expr.rs
+21
-3
src/librustc/middle/trans/meth.rs
src/librustc/middle/trans/meth.rs
+199
-168
src/librustc/middle/trans/monomorphize.rs
src/librustc/middle/trans/monomorphize.rs
+1
-5
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+48
-40
src/librustc/middle/ty_fold.rs
src/librustc/middle/ty_fold.rs
+25
-0
src/librustc/middle/typeck/infer/coercion.rs
src/librustc/middle/typeck/infer/coercion.rs
+17
-11
src/librustc/middle/typeck/infer/combine.rs
src/librustc/middle/typeck/infer/combine.rs
+32
-21
src/librustc/middle/typeck/mod.rs
src/librustc/middle/typeck/mod.rs
+14
-20
未找到文件。
src/librustc/lint/builtin.rs
浏览文件 @
088c94ae
...
...
@@ -1470,17 +1470,17 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
def_id
}
typeck
::
MethodParam
(
typeck
::
MethodParam
{
trait_
id
:
trait_id
,
trait_
ref
:
ref
trait_ref
,
method_num
:
index
,
..
})
|
typeck
::
MethodObject
(
typeck
::
MethodObject
{
trait_
id
:
trait_id
,
})
|
typeck
::
MethodObject
(
typeck
::
MethodObject
{
trait_
ref
:
ref
trait_ref
,
method_num
:
index
,
..
})
=>
{
match
ty
::
trait_item
(
cx
.tcx
,
trait_id
,
trait_
ref
.def_
id
,
index
)
{
ty
::
MethodTraitItem
(
method
)
=>
{
method
.def_id
...
...
src/librustc/metadata/common.rs
浏览文件 @
088c94ae
...
...
@@ -140,9 +140,10 @@ pub enum astencode_tag { // Reserves 0x40 -- 0x5f
tag_table_unboxed_closures
=
0x54
,
tag_table_upvar_borrow_map
=
0x55
,
tag_table_capture_modes
=
0x56
,
tag_table_object_cast_map
=
0x57
,
}
static
first_astencode_tag
:
uint
=
tag_ast
as
uint
;
static
last_astencode_tag
:
uint
=
tag_table_
capture_modes
as
uint
;
static
last_astencode_tag
:
uint
=
tag_table_
object_cast_map
as
uint
;
impl
astencode_tag
{
pub
fn
from_uint
(
value
:
uint
)
->
Option
<
astencode_tag
>
{
let
is_a_tag
=
first_astencode_tag
<=
value
&&
value
<=
last_astencode_tag
;
...
...
src/librustc/metadata/encoder.rs
浏览文件 @
088c94ae
...
...
@@ -20,9 +20,7 @@
use
metadata
::
decoder
;
use
metadata
::
tyencode
;
use
middle
::
ty
::{
lookup_item_type
};
use
middle
::
astencode
;
use
middle
::
ty
;
use
middle
::
typeck
;
use
middle
::
stability
;
use
middle
;
use
util
::
nodemap
::{
NodeMap
,
NodeSet
};
...
...
@@ -125,14 +123,6 @@ fn encode_trait_ref(rbml_w: &mut Encoder,
rbml_w
.end_tag
();
}
fn
encode_impl_vtables
(
rbml_w
:
&
mut
Encoder
,
ecx
:
&
EncodeContext
,
vtables
:
&
typeck
::
vtable_res
)
{
rbml_w
.start_tag
(
tag_item_impl_vtables
);
astencode
::
encode_vtable_res
(
ecx
,
rbml_w
,
vtables
);
rbml_w
.end_tag
();
}
// Item info table encoding
fn
encode_family
(
rbml_w
:
&
mut
Encoder
,
c
:
char
)
{
rbml_w
.start_tag
(
tag_items_data_item_family
);
...
...
@@ -191,6 +181,18 @@ pub fn write_type(ecx: &EncodeContext,
tyencode
::
enc_ty
(
rbml_w
.writer
,
ty_str_ctxt
,
typ
);
}
pub
fn
write_trait_ref
(
ecx
:
&
EncodeContext
,
rbml_w
:
&
mut
Encoder
,
trait_ref
:
&
ty
::
TraitRef
)
{
let
ty_str_ctxt
=
&
tyencode
::
ctxt
{
diag
:
ecx
.diag
,
ds
:
def_to_string
,
tcx
:
ecx
.tcx
,
abbrevs
:
&
ecx
.type_abbrevs
};
tyencode
::
enc_trait_ref
(
rbml_w
.writer
,
ty_str_ctxt
,
trait_ref
);
}
pub
fn
write_region
(
ecx
:
&
EncodeContext
,
rbml_w
:
&
mut
Encoder
,
r
:
ty
::
Region
)
{
...
...
@@ -399,7 +401,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
let
impl_items
=
ecx
.tcx.impl_items
.borrow
();
match
ecx
.tcx.inherent_impls
.borrow
()
.find
(
&
exp
.def_id
)
{
Some
(
implementations
)
=>
{
for
base_impl_did
in
implementations
.
borrow
()
.
iter
()
{
for
base_impl_did
in
implementations
.iter
()
{
for
&
method_did
in
impl_items
.get
(
base_impl_did
)
.iter
()
{
let
impl_item
=
ty
::
impl_or_trait_item
(
ecx
.tcx
,
...
...
@@ -946,7 +948,7 @@ fn encode_inherent_implementations(ecx: &EncodeContext,
match
ecx
.tcx.inherent_impls
.borrow
()
.find
(
&
def_id
)
{
None
=>
{}
Some
(
implementations
)
=>
{
for
&
impl_def_id
in
implementations
.
borrow
()
.
iter
()
{
for
&
impl_def_id
in
implementations
.iter
()
{
rbml_w
.start_tag
(
tag_items_data_item_inherent_impl
);
encode_def_id
(
rbml_w
,
impl_def_id
);
rbml_w
.end_tag
();
...
...
@@ -1203,8 +1205,6 @@ fn add_to_index(item: &Item, rbml_w: &Encoder,
let
trait_ref
=
ty
::
node_id_to_trait_ref
(
tcx
,
ast_trait_ref
.ref_id
);
encode_trait_ref
(
rbml_w
,
ecx
,
&*
trait_ref
,
tag_item_trait_ref
);
let
impl_vtables
=
ty
::
lookup_impl_vtables
(
tcx
,
def_id
);
encode_impl_vtables
(
rbml_w
,
ecx
,
&
impl_vtables
);
}
encode_path
(
rbml_w
,
path
.clone
());
encode_stability
(
rbml_w
,
stab
);
...
...
src/librustc/middle/astencode.rs
浏览文件 @
088c94ae
...
...
@@ -43,6 +43,7 @@
use
std
::
io
::
Seek
;
use
std
::
mem
;
use
std
::
gc
::
GC
;
use
std
::
rc
::
Rc
;
use
rbml
::
io
::
SeekableMemWriter
;
use
rbml
::{
reader
,
writer
};
...
...
@@ -589,7 +590,7 @@ fn encode_method_callee(ecx: &e::EncodeContext,
adjustment
.encode
(
rbml_w
)
});
rbml_w
.emit_struct_field
(
"origin"
,
1u
,
|
rbml_w
|
{
method
.origin
.encode
(
rbml_w
)
Ok
(
rbml_w
.emit_method_origin
(
ecx
,
&
method
.origin
)
)
});
rbml_w
.emit_struct_field
(
"ty"
,
2u
,
|
rbml_w
|
{
Ok
(
rbml_w
.emit_ty
(
ecx
,
method
.ty
))
...
...
@@ -610,9 +611,7 @@ fn read_method_callee(&mut self, dcx: &DecodeContext)
})
.unwrap
();
Ok
((
adjustment
,
MethodCallee
{
origin
:
this
.read_struct_field
(
"origin"
,
1
,
|
this
|
{
let
method_origin
:
MethodOrigin
=
Decodable
::
decode
(
this
)
.unwrap
();
Ok
(
method_origin
.tr
(
dcx
))
Ok
(
this
.read_method_origin
(
dcx
))
})
.unwrap
(),
ty
:
this
.read_struct_field
(
"ty"
,
2
,
|
this
|
{
Ok
(
this
.read_ty
(
dcx
))
...
...
@@ -635,15 +634,16 @@ fn tr(&self, dcx: &DecodeContext) -> MethodOrigin {
typeck
::
MethodParam
(
ref
mp
)
=>
{
typeck
::
MethodParam
(
typeck
::
MethodParam
{
trait_id
:
mp
.trait_id
.tr
(
dcx
),
..
*
mp
// def-id is already translated when we read it out
trait_ref
:
mp
.trait_ref
.clone
(),
method_num
:
mp
.method_num
,
}
)
}
typeck
::
MethodObject
(
ref
mo
)
=>
{
typeck
::
MethodObject
(
typeck
::
MethodObject
{
trait_
id
:
mo
.trait_id
.tr
(
dcx
),
trait_
ref
:
mo
.trait_ref
.clone
(
),
..
*
mo
}
)
...
...
@@ -655,22 +655,6 @@ fn tr(&self, dcx: &DecodeContext) -> MethodOrigin {
// ______________________________________________________________________
// Encoding and decoding vtable_res
fn
encode_vtable_res_with_key
(
ecx
:
&
e
::
EncodeContext
,
rbml_w
:
&
mut
Encoder
,
adjustment
:
typeck
::
ExprAdjustment
,
dr
:
&
typeck
::
vtable_res
)
{
use
serialize
::
Encoder
;
rbml_w
.emit_struct
(
"VtableWithKey"
,
2
,
|
rbml_w
|
{
rbml_w
.emit_struct_field
(
"adjustment"
,
0u
,
|
rbml_w
|
{
adjustment
.encode
(
rbml_w
)
});
rbml_w
.emit_struct_field
(
"vtable_res"
,
1u
,
|
rbml_w
|
{
Ok
(
encode_vtable_res
(
ecx
,
rbml_w
,
dr
))
})
})
.unwrap
()
}
pub
fn
encode_vtable_res
(
ecx
:
&
e
::
EncodeContext
,
rbml_w
:
&
mut
Encoder
,
dr
:
&
typeck
::
vtable_res
)
{
...
...
@@ -913,11 +897,15 @@ trait rbml_writer_helpers {
fn
emit_closure_type
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
closure_type
:
&
ty
::
ClosureTy
);
fn
emit_method_origin
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
method_origin
:
&
typeck
::
MethodOrigin
);
fn
emit_ty
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
ty
:
ty
::
t
);
fn
emit_tys
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
tys
:
&
[
ty
::
t
]);
fn
emit_type_param_def
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
type_param_def
:
&
ty
::
TypeParameterDef
);
fn
emit_trait_ref
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
ty
:
&
ty
::
TraitRef
);
fn
emit_polytype
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
pty
:
ty
::
Polytype
);
...
...
@@ -939,6 +927,63 @@ fn emit_closure_type(&mut self,
});
}
fn
emit_method_origin
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
method_origin
:
&
typeck
::
MethodOrigin
)
{
use
serialize
::
Encoder
;
self
.emit_enum
(
"MethodOrigin"
,
|
this
|
{
match
*
method_origin
{
typeck
::
MethodStatic
(
def_id
)
=>
{
this
.emit_enum_variant
(
"MethodStatic"
,
0
,
1
,
|
this
|
{
Ok
(
this
.emit_def_id
(
def_id
))
})
}
typeck
::
MethodStaticUnboxedClosure
(
def_id
)
=>
{
this
.emit_enum_variant
(
"MethodStaticUnboxedClosure"
,
1
,
1
,
|
this
|
{
Ok
(
this
.emit_def_id
(
def_id
))
})
}
typeck
::
MethodParam
(
ref
p
)
=>
{
this
.emit_enum_variant
(
"MethodParam"
,
2
,
1
,
|
this
|
{
this
.emit_struct
(
"MethodParam"
,
2
,
|
this
|
{
try!
(
this
.emit_struct_field
(
"trait_ref"
,
0
,
|
this
|
{
Ok
(
this
.emit_trait_ref
(
ecx
,
&*
p
.trait_ref
))
}));
try!
(
this
.emit_struct_field
(
"method_num"
,
0
,
|
this
|
{
this
.emit_uint
(
p
.method_num
)
}));
Ok
(())
})
})
}
typeck
::
MethodObject
(
ref
o
)
=>
{
this
.emit_enum_variant
(
"MethodObject"
,
3
,
1
,
|
this
|
{
this
.emit_struct
(
"MethodObject"
,
2
,
|
this
|
{
try!
(
this
.emit_struct_field
(
"trait_ref"
,
0
,
|
this
|
{
Ok
(
this
.emit_trait_ref
(
ecx
,
&*
o
.trait_ref
))
}));
try!
(
this
.emit_struct_field
(
"object_trait_id"
,
0
,
|
this
|
{
Ok
(
this
.emit_def_id
(
o
.object_trait_id
))
}));
try!
(
this
.emit_struct_field
(
"method_num"
,
0
,
|
this
|
{
this
.emit_uint
(
o
.method_num
)
}));
try!
(
this
.emit_struct_field
(
"real_index"
,
0
,
|
this
|
{
this
.emit_uint
(
o
.real_index
)
}));
Ok
(())
})
})
}
}
});
}
fn
emit_ty
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
ty
:
ty
::
t
)
{
self
.emit_opaque
(|
this
|
Ok
(
e
::
write_type
(
ecx
,
this
,
ty
)));
}
...
...
@@ -947,6 +992,12 @@ fn emit_tys(&mut self, ecx: &e::EncodeContext, tys: &[ty::t]) {
self
.emit_from_vec
(
tys
,
|
this
,
ty
|
Ok
(
this
.emit_ty
(
ecx
,
*
ty
)));
}
fn
emit_trait_ref
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
trait_ref
:
&
ty
::
TraitRef
)
{
self
.emit_opaque
(|
this
|
Ok
(
e
::
write_trait_ref
(
ecx
,
this
,
trait_ref
)));
}
fn
emit_type_param_def
(
&
mut
self
,
ecx
:
&
e
::
EncodeContext
,
type_param_def
:
&
ty
::
TypeParameterDef
)
{
...
...
@@ -1103,12 +1154,16 @@ fn emit_unsize_kind(&mut self, ecx: &e::EncodeContext, uk: &ty::UnsizeKind) {
this
.emit_enum_variant_arg
(
1
,
|
this
|
idx
.encode
(
this
))
})
}
ty
::
UnsizeVtable
(
ref
b
,
def_id
,
ref
substs
)
=>
{
this
.emit_enum_variant
(
"UnsizeVtable"
,
2
,
3
,
|
this
|
{
ty
::
UnsizeVtable
(
ty
::
TyTrait
{
def_id
:
def_id
,
bounds
:
ref
b
,
substs
:
ref
substs
},
self_ty
)
=>
{
this
.emit_enum_variant
(
"UnsizeVtable"
,
2
,
4
,
|
this
|
{
this
.emit_enum_variant_arg
(
0
,
|
this
|
Ok
(
this
.emit_existential_bounds
(
ecx
,
b
)));
this
.emit_enum_variant_arg
(
1
,
|
this
|
def_id
.encode
(
this
));
this
.emit_enum_variant_arg
(
2
,
|
this
|
Ok
(
this
.emit_substs
(
ecx
,
substs
)))
this
.emit_enum_variant_arg
(
2
,
|
this
|
Ok
(
this
.emit_ty
(
ecx
,
self_ty
)));
this
.emit_enum_variant_arg
(
3
,
|
this
|
Ok
(
this
.emit_substs
(
ecx
,
substs
)))
})
}
}
...
...
@@ -1282,11 +1337,11 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
})
}
for
&
dr
in
tcx
.vtable_map
.borrow
()
.find
(
&
method_call
)
.iter
()
{
rbml_w
.tag
(
c
::
tag_table_
vtable
_map
,
|
rbml_w
|
{
for
&
trait_ref
in
tcx
.object_cast_map
.borrow
()
.find
(
&
id
)
.iter
()
{
rbml_w
.tag
(
c
::
tag_table_
object_cast
_map
,
|
rbml_w
|
{
rbml_w
.id
(
id
);
rbml_w
.tag
(
c
::
tag_table_val
,
|
rbml_w
|
{
encode_vtable_res_with_key
(
ecx
,
rbml_w
,
method_call
.adjustment
,
dr
);
rbml_w
.emit_trait_ref
(
ecx
,
&**
trait_ref
);
})
})
}
...
...
@@ -1303,15 +1358,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
})
})
}
for
&
dr
in
tcx
.vtable_map
.borrow
()
.find
(
&
method_call
)
.iter
()
{
rbml_w
.tag
(
c
::
tag_table_vtable_map
,
|
rbml_w
|
{
rbml_w
.id
(
id
);
rbml_w
.tag
(
c
::
tag_table_val
,
|
rbml_w
|
{
encode_vtable_res_with_key
(
ecx
,
rbml_w
,
method_call
.adjustment
,
dr
);
})
})
}
}
ty
::
AutoDerefRef
(
ref
adj
)
=>
{
assert
!
(
!
ty
::
adjust_is_object
(
adjustment
));
...
...
@@ -1326,16 +1372,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
})
})
}
for
&
dr
in
tcx
.vtable_map
.borrow
()
.find
(
&
method_call
)
.iter
()
{
rbml_w
.tag
(
c
::
tag_table_vtable_map
,
|
rbml_w
|
{
rbml_w
.id
(
id
);
rbml_w
.tag
(
c
::
tag_table_val
,
|
rbml_w
|
{
encode_vtable_res_with_key
(
ecx
,
rbml_w
,
method_call
.adjustment
,
dr
);
})
})
}
}
}
_
=>
{
...
...
@@ -1378,8 +1414,10 @@ fn opt_child(&self, tag: c::astencode_tag) -> Option<rbml::Doc<'a>> {
}
trait
rbml_decoder_decoder_helpers
{
fn
read_method_origin
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
typeck
::
MethodOrigin
;
fn
read_ty
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
ty
::
t
;
fn
read_tys
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
Vec
<
ty
::
t
>
;
fn
read_trait_ref
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
Rc
<
ty
::
TraitRef
>
;
fn
read_type_param_def
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
ty
::
TypeParameterDef
;
fn
read_polytype
(
&
mut
self
,
dcx
:
&
DecodeContext
)
...
...
@@ -1447,6 +1485,77 @@ fn read_substs_nodcx(&mut self,
})
.unwrap
()
}
fn
read_method_origin
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
typeck
::
MethodOrigin
{
self
.read_enum
(
"MethodOrigin"
,
|
this
|
{
let
variants
=
[
"MethodStatic"
,
"MethodStaticUnboxedClosure"
,
"MethodParam"
,
"MethodObject"
];
this
.read_enum_variant
(
variants
,
|
this
,
i
|
{
Ok
(
match
i
{
0
=>
{
let
def_id
=
this
.read_def_id
(
dcx
);
typeck
::
MethodStatic
(
def_id
)
}
1
=>
{
let
def_id
=
this
.read_def_id
(
dcx
);
typeck
::
MethodStaticUnboxedClosure
(
def_id
)
}
2
=>
{
this
.read_struct
(
"MethodParam"
,
2
,
|
this
|
{
Ok
(
typeck
::
MethodParam
(
typeck
::
MethodParam
{
trait_ref
:
{
this
.read_struct_field
(
"trait_ref"
,
0
,
|
this
|
{
Ok
(
this
.read_trait_ref
(
dcx
))
})
.unwrap
()
},
method_num
:
{
this
.read_struct_field
(
"method_num"
,
1
,
|
this
|
{
this
.read_uint
()
})
.unwrap
()
}
}))
})
.unwrap
()
}
3
=>
{
this
.read_struct
(
"MethodObject"
,
2
,
|
this
|
{
Ok
(
typeck
::
MethodObject
(
typeck
::
MethodObject
{
trait_ref
:
{
this
.read_struct_field
(
"trait_ref"
,
0
,
|
this
|
{
Ok
(
this
.read_trait_ref
(
dcx
))
})
.unwrap
()
},
object_trait_id
:
{
this
.read_struct_field
(
"object_trait_id"
,
1
,
|
this
|
{
Ok
(
this
.read_def_id
(
dcx
))
})
.unwrap
()
},
method_num
:
{
this
.read_struct_field
(
"method_num"
,
2
,
|
this
|
{
this
.read_uint
()
})
.unwrap
()
},
real_index
:
{
this
.read_struct_field
(
"real_index"
,
3
,
|
this
|
{
this
.read_uint
()
})
.unwrap
()
},
}))
})
.unwrap
()
}
_
=>
fail
!
(
".."
)
})
})
})
.unwrap
()
}
fn
read_ty
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
ty
::
t
{
// Note: regions types embed local node ids. In principle, we
// should translate these node ids into the new decode
...
...
@@ -1479,6 +1588,18 @@ fn read_tys(&mut self, dcx: &DecodeContext) -> Vec<ty::t> {
self
.read_to_vec
(|
this
|
Ok
(
this
.read_ty
(
dcx
)))
.unwrap
()
.move_iter
()
.collect
()
}
fn
read_trait_ref
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
Rc
<
ty
::
TraitRef
>
{
Rc
::
new
(
self
.read_opaque
(|
this
,
doc
|
{
let
ty
=
tydecode
::
parse_trait_ref_data
(
doc
.data
,
dcx
.cdata.cnum
,
doc
.start
,
dcx
.tcx
,
|
s
,
a
|
this
.convert_def_id
(
dcx
,
s
,
a
));
Ok
(
ty
)
})
.unwrap
())
}
fn
read_type_param_def
(
&
mut
self
,
dcx
:
&
DecodeContext
)
->
ty
::
TypeParameterDef
{
self
.read_opaque
(|
this
,
doc
|
{
...
...
@@ -1667,10 +1788,14 @@ fn read_unsize_kind(&mut self, dcx: &DecodeContext) -> ty::UnsizeKind {
0
,
|
this
|
Ok
(
this
.read_existential_bounds
(
dcx
)))
.unwrap
();
let
def_id
:
ast
::
DefId
=
this
.read_enum_variant_arg
(
1
,
|
this
|
Decodable
::
decode
(
this
))
.unwrap
();
let
substs
=
this
.read_enum_variant_arg
(
2
,
let
self_ty
=
this
.read_enum_variant_arg
(
2
,
|
this
|
Ok
(
this
.read_ty
(
dcx
)))
.unwrap
();
let
substs
=
this
.read_enum_variant_arg
(
3
,
|
this
|
Ok
(
this
.read_substs
(
dcx
)))
.unwrap
();
ty
::
UnsizeVtable
(
b
,
def_id
.tr
(
dcx
),
substs
)
let
ty_trait
=
ty
::
TyTrait
{
def_id
:
def_id
.tr
(
dcx
),
bounds
:
b
,
substs
:
substs
};
ty
::
UnsizeVtable
(
ty_trait
,
self_ty
)
}
_
=>
fail
!
(
"bad enum variant for ty::UnsizeKind"
)
})
...
...
@@ -1828,15 +1953,10 @@ fn decode_side_tables(dcx: &DecodeContext,
};
dcx
.tcx.method_map
.borrow_mut
()
.insert
(
method_call
,
method
);
}
c
::
tag_table_vtable_map
=>
{
let
(
adjustment
,
vtable_res
)
=
val_dsr
.read_vtable_res_with_key
(
dcx
.tcx
,
dcx
.cdata
);
let
vtable_key
=
MethodCall
{
expr_id
:
id
,
adjustment
:
adjustment
};
dcx
.tcx.vtable_map
.borrow_mut
()
.insert
(
vtable_key
,
vtable_res
);
c
::
tag_table_object_cast_map
=>
{
let
trait_ref
=
val_dsr
.read_trait_ref
(
dcx
);
dcx
.tcx.object_cast_map
.borrow_mut
()
.insert
(
id
,
trait_ref
);
}
c
::
tag_table_adjustments
=>
{
let
adj
:
ty
::
AutoAdjustment
=
val_dsr
.read_auto_adjustment
(
dcx
);
...
...
src/librustc/middle/dead.rs
浏览文件 @
088c94ae
...
...
@@ -102,17 +102,17 @@ fn lookup_and_handle_method(&mut self, id: ast::NodeId,
}
typeck
::
MethodStaticUnboxedClosure
(
_
)
=>
{}
typeck
::
MethodParam
(
typeck
::
MethodParam
{
trait_
id
:
trait_id
,
trait_
ref
:
ref
trait_ref
,
method_num
:
index
,
..
})
|
typeck
::
MethodObject
(
typeck
::
MethodObject
{
trait_
id
:
trait_id
,
})
|
typeck
::
MethodObject
(
typeck
::
MethodObject
{
trait_
ref
:
ref
trait_ref
,
method_num
:
index
,
..
})
=>
{
let
trait_item
=
ty
::
trait_item
(
self
.tcx
,
trait_id
,
trait_
ref
.def_
id
,
index
);
match
trait_item
{
ty
::
MethodTraitItem
(
method
)
=>
{
...
...
src/librustc/middle/expr_use_visitor.rs
浏览文件 @
088c94ae
...
...
@@ -174,11 +174,9 @@ fn from_method_origin(tcx: &ty::ctxt, origin: &MethodOrigin)
MethodStaticUnboxedClosure
(
def_id
)
=>
{
OverloadedCallType
::
from_unboxed_closure
(
tcx
,
def_id
)
}
MethodParam
(
ref
method_param
)
=>
{
OverloadedCallType
::
from_trait_id
(
tcx
,
method_param
.trait_id
)
}
MethodObject
(
ref
method_object
)
=>
{
OverloadedCallType
::
from_trait_id
(
tcx
,
method_object
.trait_id
)
MethodParam
(
MethodParam
{
trait_ref
:
ref
trait_ref
,
..
})
|
MethodObject
(
MethodObject
{
trait_ref
:
ref
trait_ref
,
..
})
=>
{
OverloadedCallType
::
from_trait_id
(
tcx
,
trait_ref
.def_id
)
}
}
}
...
...
src/librustc/middle/privacy.rs
浏览文件 @
088c94ae
...
...
@@ -782,19 +782,19 @@ fn check_path(&mut self, span: Span, path_id: ast::NodeId, path: &ast::Path) {
}
// Checks that a method is in scope.
fn
check_method
(
&
mut
self
,
span
:
Span
,
origin
:
MethodOrigin
,
fn
check_method
(
&
mut
self
,
span
:
Span
,
origin
:
&
MethodOrigin
,
ident
:
ast
::
Ident
)
{
match
origin
{
match
*
origin
{
MethodStatic
(
method_id
)
=>
{
self
.check_static_method
(
span
,
method_id
,
ident
)
}
MethodStaticUnboxedClosure
(
_
)
=>
{}
// Trait methods are always all public. The only controlling factor
// is whether the trait itself is accessible or not.
MethodParam
(
MethodParam
{
trait_
id
:
trait_id
,
..
})
|
MethodObject
(
MethodObject
{
trait_
id
:
trait_id
,
..
})
=>
{
self
.report_error
(
self
.ensure_public
(
span
,
trait_
id
,
None
,
"source trait"
));
MethodParam
(
MethodParam
{
trait_
ref
:
ref
trait_ref
,
..
})
|
MethodObject
(
MethodObject
{
trait_
ref
:
ref
trait_ref
,
..
})
=>
{
self
.report_error
(
self
.ensure_public
(
span
,
trait_
ref
.def_id
,
None
,
"source trait"
));
}
}
}
...
...
@@ -835,7 +835,7 @@ fn visit_expr(&mut self, expr: &ast::Expr) {
}
Some
(
method
)
=>
{
debug!
(
"(privacy checking) checking impl method"
);
self
.check_method
(
expr
.span
,
method
.origin
,
ident
.node
);
self
.check_method
(
expr
.span
,
&
method
.origin
,
ident
.node
);
}
}
}
...
...
src/librustc/middle/save/mod.rs
浏览文件 @
088c94ae
...
...
@@ -908,10 +908,10 @@ fn process_method_call(&mut self,
};
(
Some
(
def_id
),
decl_id
)
}
typeck
::
MethodParam
(
mp
)
=>
{
typeck
::
MethodParam
(
ref
mp
)
=>
{
// method invoked on a type parameter
let
trait_item
=
ty
::
trait_item
(
&
self
.analysis.ty_cx
,
mp
.trait_id
,
mp
.trait_
ref.def_
id
,
mp
.method_num
);
match
trait_item
{
ty
::
MethodTraitItem
(
method
)
=>
{
...
...
@@ -919,10 +919,10 @@ fn process_method_call(&mut self,
}
}
},
typeck
::
MethodObject
(
mo
)
=>
{
typeck
::
MethodObject
(
ref
mo
)
=>
{
// method invoked on a trait instance
let
trait_item
=
ty
::
trait_item
(
&
self
.analysis.ty_cx
,
mo
.trait_id
,
mo
.trait_
ref.def_
id
,
mo
.method_num
);
match
trait_item
{
ty
::
MethodTraitItem
(
method
)
=>
{
...
...
src/librustc/middle/subst.rs
浏览文件 @
088c94ae
...
...
@@ -164,6 +164,11 @@ pub fn with_self_ty(&self, self_ty: ty::t) -> Substs {
s
}
pub
fn
erase_regions
(
self
)
->
Substs
{
let
Substs
{
types
:
types
,
regions
:
_
}
=
self
;
Substs
{
types
:
types
,
regions
:
ErasedRegions
}
}
pub
fn
regions
<
'a
>
(
&
'a
self
)
->
&
'a
VecPerParamSpace
<
ty
::
Region
>
{
/*!
* Since ErasedRegions are only to be used in trans, most of
...
...
src/librustc/middle/trans/base.rs
浏览文件 @
088c94ae
...
...
@@ -75,7 +75,6 @@
use
middle
::
trans
::
type_of
::
*
;
use
middle
::
trans
::
value
::
Value
;
use
middle
::
ty
;
use
middle
::
typeck
;
use
util
::
common
::
indenter
;
use
util
::
ppaux
::{
Repr
,
ty_to_string
};
use
util
::
sha2
::
Sha256
;
...
...
@@ -547,8 +546,7 @@ pub fn get_res_dtor(ccx: &CrateContext,
// Since we're in trans we don't care for any region parameters
let
ref
substs
=
subst
::
Substs
::
erased
(
substs
.types
.clone
());
let
vtables
=
typeck
::
check
::
vtable
::
trans_resolve_method
(
ccx
.tcx
(),
did
.node
,
substs
);
let
(
val
,
_
)
=
monomorphize
::
monomorphic_fn
(
ccx
,
did
,
substs
,
vtables
,
None
);
let
(
val
,
_
)
=
monomorphize
::
monomorphic_fn
(
ccx
,
did
,
substs
,
None
);
val
}
else
if
did
.krate
==
ast
::
LOCAL_CRATE
{
...
...
src/librustc/middle/trans/callee.rs
浏览文件 @
088c94ae
...
...
@@ -25,7 +25,7 @@
use
metadata
::
csearch
;
use
middle
::
def
;
use
middle
::
subst
;
use
middle
::
subst
::{
Subst
,
VecPerParamSpace
};
use
middle
::
subst
::{
Subst
};
use
middle
::
trans
::
adt
;
use
middle
::
trans
::
base
;
use
middle
::
trans
::
base
::
*
;
...
...
@@ -47,7 +47,6 @@
use
middle
::
trans
::
type_
::
Type
;
use
middle
::
trans
::
type_of
;
use
middle
::
ty
;
use
middle
::
typeck
;
use
middle
::
typeck
::
coherence
::
make_substs_for_receiver_types
;
use
middle
::
typeck
::
MethodCall
;
use
util
::
ppaux
::
Repr
;
...
...
@@ -227,61 +226,27 @@ pub fn trans_fn_ref(bcx: Block, def_id: ast::DefId, node: ExprOrMethodCall) -> V
let
_
icx
=
push_ctxt
(
"trans_fn_ref"
);
let
substs
=
node_id_substs
(
bcx
,
node
);
let
vtable_key
=
match
node
{
ExprId
(
id
)
=>
MethodCall
::
expr
(
id
),
MethodCall
(
method_call
)
=>
method_call
};
let
vtables
=
node_vtables
(
bcx
,
vtable_key
);
debug!
(
"trans_fn_ref(def_id={}, node={:?}, substs={}, vtables={})"
,
debug!
(
"trans_fn_ref(def_id={}, node={:?}, substs={})"
,
def_id
.repr
(
bcx
.tcx
()),
node
,
substs
.repr
(
bcx
.tcx
()),
vtables
.repr
(
bcx
.tcx
()));
trans_fn_ref_with_vtables
(
bcx
,
def_id
,
node
,
substs
,
vtables
)
substs
.repr
(
bcx
.tcx
()));
trans_fn_ref_with_substs
(
bcx
,
def_id
,
node
,
substs
)
}
fn
trans_fn_ref_with_vtables_to_callee
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
def_id
:
ast
::
DefId
,
ref_id
:
ast
::
NodeId
,
substs
:
subst
::
Substs
,
vtables
:
typeck
::
vtable_res
)
->
Callee
<
'blk
,
'tcx
>
{
fn
trans_fn_ref_with_substs_to_callee
<
'blk
,
'tcx
>
(
bcx
:
Block
<
'blk
,
'tcx
>
,
def_id
:
ast
::
DefId
,
ref_id
:
ast
::
NodeId
,
substs
:
subst
::
Substs
)
->
Callee
<
'blk
,
'tcx
>
{
Callee
{
bcx
:
bcx
,
data
:
Fn
(
trans_fn_ref_with_vtables
(
bcx
,
def_id
,
ExprId
(
ref_id
),
substs
,
vtables
)),
data
:
Fn
(
trans_fn_ref_with_substs
(
bcx
,
def_id
,
ExprId
(
ref_id
),
substs
)),
}
}
fn
resolve_default_method_vtables
(
bcx
:
Block
,
impl_id
:
ast
::
DefId
,
substs
:
&
subst
::
Substs
,
impl_vtables
:
typeck
::
vtable_res
)
->
typeck
::
vtable_res
{
// Get the vtables that the impl implements the trait at
let
impl_res
=
ty
::
lookup_impl_vtables
(
bcx
.tcx
(),
impl_id
);
// Build up a param_substs that we are going to resolve the
// trait_vtables under.
let
param_substs
=
param_substs
{
substs
:
(
*
substs
)
.clone
(),
vtables
:
impl_vtables
.clone
()
};
let
mut
param_vtables
=
resolve_vtables_under_param_substs
(
bcx
.tcx
(),
&
param_substs
,
&
impl_res
);
// Now we pull any vtables for parameters on the actual method.
param_vtables
.push_all
(
subst
::
FnSpace
,
impl_vtables
.get_slice
(
subst
::
FnSpace
));
param_vtables
}
/// Translates the adapter that deconstructs a `Box<Trait>` object into
/// `Trait` so that a by-value self method can be called.
pub
fn
trans_unboxing_shim
(
bcx
:
Block
,
...
...
@@ -408,12 +373,11 @@ pub fn trans_unboxing_shim(bcx: Block,
llfn
}
pub
fn
trans_fn_ref_with_
vtable
s
(
pub
fn
trans_fn_ref_with_
subst
s
(
bcx
:
Block
,
//
def_id
:
ast
::
DefId
,
// def id of fn
node
:
ExprOrMethodCall
,
// node id of use of fn; may be zero if N/A
substs
:
subst
::
Substs
,
// values for fn's ty params
vtables
:
typeck
::
vtable_res
)
// vtables for the call
substs
:
subst
::
Substs
)
// vtables for the call
->
ValueRef
{
/*!
...
...
@@ -428,20 +392,18 @@ pub fn trans_fn_ref_with_vtables(
* This parameter may be zero; but, if so, the resulting value may not
* have the right type, so it must be cast before being used.
* - `substs`: values for each of the fn/method's parameters
* - `vtables`: values for each bound on each of the type parameters
*/
let
_
icx
=
push_ctxt
(
"trans_fn_ref_with_
vtable
s"
);
let
_
icx
=
push_ctxt
(
"trans_fn_ref_with_
subst
s"
);
let
ccx
=
bcx
.ccx
();
let
tcx
=
bcx
.tcx
();
debug!
(
"trans_fn_ref_with_
vtable
s(bcx={}, def_id={}, node={:?},
\
substs={}
, vtables={}
)"
,
debug!
(
"trans_fn_ref_with_
subst
s(bcx={}, def_id={}, node={:?},
\
substs={})"
,
bcx
.to_str
(),
def_id
.repr
(
tcx
),
node
,
substs
.repr
(
tcx
),
vtables
.repr
(
tcx
));
substs
.repr
(
tcx
));
assert
!
(
substs
.types
.all
(|
t
|
!
ty
::
type_needs_infer
(
*
t
)));
...
...
@@ -456,9 +418,8 @@ pub fn trans_fn_ref_with_vtables(
// We need to do a bunch of special handling for default methods.
// We need to modify the def_id and our substs in order to monomorphize
// the function.
let
(
is_default
,
def_id
,
substs
,
vtables
)
=
match
ty
::
provided_source
(
tcx
,
def_id
)
{
None
=>
(
false
,
def_id
,
substs
,
vtables
),
let
(
is_default
,
def_id
,
substs
)
=
match
ty
::
provided_source
(
tcx
,
def_id
)
{
None
=>
(
false
,
def_id
,
substs
),
Some
(
source_id
)
=>
{
// There are two relevant substitutions when compiling
// default methods. First, there is the substitution for
...
...
@@ -491,23 +452,11 @@ pub fn trans_fn_ref_with_vtables(
debug!
(
"trans_fn_with_vtables - default method:
\
substs = {}, trait_subst = {},
\
first_subst = {}, new_subst = {},
\
vtables = {}"
,
first_subst = {}, new_subst = {}"
,
substs
.repr
(
tcx
),
trait_ref
.substs
.repr
(
tcx
),
first_subst
.repr
(
tcx
),
new_substs
.repr
(
tcx
),
vtables
.repr
(
tcx
));
let
param_vtables
=
resolve_default_method_vtables
(
bcx
,
impl_id
,
&
substs
,
vtables
);
debug!
(
"trans_fn_with_vtables - default method:
\
param_vtables = {}"
,
param_vtables
.repr
(
tcx
));
first_subst
.repr
(
tcx
),
new_substs
.repr
(
tcx
));
(
true
,
source_id
,
new_substs
,
param_vtables
)
(
true
,
source_id
,
new_substs
)
}
}
}
...
...
@@ -556,8 +505,7 @@ pub fn trans_fn_ref_with_vtables(
};
let
(
val
,
must_cast
)
=
monomorphize
::
monomorphic_fn
(
ccx
,
def_id
,
&
substs
,
vtables
,
opt_ref_id
);
monomorphize
::
monomorphic_fn
(
ccx
,
def_id
,
&
substs
,
opt_ref_id
);
let
mut
val
=
val
;
if
must_cast
&&
node
!=
ExprId
(
0
)
{
// Monotype of the REFERENCE to the function (type params
...
...
@@ -678,11 +626,10 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
None
,
fty
,
|
bcx
,
_
|
{
trans_fn_ref_with_vtables_to_callee
(
bcx
,
did
,
0
,
subst
::
Substs
::
empty
(),
VecPerParamSpace
::
empty
())
trans_fn_ref_with_substs_to_callee
(
bcx
,
did
,
0
,
subst
::
Substs
::
empty
())
},
ArgVals
(
args
),
dest
)
...
...
src/librustc/middle/trans/common.rs
浏览文件 @
088c94ae
...
...
@@ -29,8 +29,11 @@
use
middle
::
trans
::
debuginfo
;
use
middle
::
trans
::
type_
::
Type
;
use
middle
::
trans
::
type_of
;
use
middle
::
traits
;
use
middle
::
ty
;
use
middle
::
ty_fold
;
use
middle
::
typeck
;
use
middle
::
typeck
::
infer
;
use
util
::
ppaux
::
Repr
;
use
util
::
nodemap
::{
DefIdMap
,
NodeMap
};
...
...
@@ -39,6 +42,7 @@
use
libc
::{
c_uint
,
c_longlong
,
c_ulonglong
,
c_char
};
use
std
::
c_str
::
ToCStr
;
use
std
::
cell
::{
Cell
,
RefCell
};
use
std
::
rc
::
Rc
;
use
std
::
vec
::
Vec
;
use
syntax
::
ast
::
Ident
;
use
syntax
::
ast
;
...
...
@@ -188,14 +192,12 @@ pub fn BuilderRef_res(b: BuilderRef) -> BuilderRef_res {
// will only be set in the case of default methods.
pub
struct
param_substs
{
pub
substs
:
subst
::
Substs
,
pub
vtables
:
typeck
::
vtable_res
,
}
impl
param_substs
{
pub
fn
empty
()
->
param_substs
{
param_substs
{
substs
:
subst
::
Substs
::
trans_empty
(),
vtables
:
subst
::
VecPerParamSpace
::
empty
(),
}
}
...
...
@@ -204,15 +206,9 @@ pub fn validate(&self) {
}
}
fn
param_substs_to_string
(
this
:
&
param_substs
,
tcx
:
&
ty
::
ctxt
)
->
String
{
format!
(
"param_substs(substs={},vtables={})"
,
this
.substs
.repr
(
tcx
),
this
.vtables
.repr
(
tcx
))
}
impl
Repr
for
param_substs
{
fn
repr
(
&
self
,
tcx
:
&
ty
::
ctxt
)
->
String
{
param_substs_to_string
(
self
,
tcx
)
self
.substs
.repr
(
tcx
)
}
}
...
...
@@ -766,6 +762,98 @@ pub fn expr_ty_adjusted(bcx: Block, ex: &ast::Expr) -> ty::t {
monomorphize_type
(
bcx
,
ty
::
expr_ty_adjusted
(
bcx
.tcx
(),
ex
))
}
pub
fn
fulfill_obligation
(
ccx
:
&
CrateContext
,
span
:
Span
,
trait_ref
:
Rc
<
ty
::
TraitRef
>
)
->
traits
::
Vtable
<
()
>
{
/*!
* Attempts to resolve an obligation. The result is a shallow
* vtable resolution -- meaning that we do not (necessarily) resolve
* all nested obligations on the impl. Note that type check should
* guarantee to us that all nested obligations *could be* resolved
* if we wanted to.
*/
let
tcx
=
ccx
.tcx
();
// Remove any references to regions; this helps improve caching.
let
trait_ref
=
ty_fold
::
erase_regions
(
tcx
,
trait_ref
);
// First check the cache.
match
ccx
.trait_cache
()
.borrow
()
.find
(
&
trait_ref
)
{
Some
(
vtable
)
=>
{
info!
(
"Cache hit: {}"
,
trait_ref
.repr
(
ccx
.tcx
()));
return
(
*
vtable
)
.clone
();
}
None
=>
{
}
}
ty
::
populate_implementations_for_trait_if_necessary
(
tcx
,
trait_ref
.def_id
);
let
infcx
=
infer
::
new_infer_ctxt
(
tcx
);
// Parameter environment is used to give details about type parameters,
// but since we are in trans, everything is fully monomorphized.
let
param_env
=
ty
::
empty_parameter_environment
();
let
unboxed_closures
=
tcx
.unboxed_closures
.borrow
();
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
let
selcx
=
traits
::
SelectionContext
::
new
(
&
infcx
,
&
param_env
,
&*
unboxed_closures
);
let
obligation
=
traits
::
Obligation
::
misc
(
span
,
trait_ref
.clone
());
let
selection
=
match
selcx
.select
(
&
obligation
)
{
Ok
(
Some
(
selection
))
=>
selection
,
Ok
(
None
)
=>
{
tcx
.sess
.span_bug
(
span
,
format!
(
"Encountered ambiguity selecting `{}` during trans"
,
trait_ref
.repr
(
tcx
))
.as_slice
())
}
Err
(
e
)
=>
{
tcx
.sess
.span_bug
(
span
,
format!
(
"Encountered error `{}` selecting `{}` during trans"
,
e
.repr
(
tcx
),
trait_ref
.repr
(
tcx
))
.as_slice
())
}
};
// Currently, we use a fulfillment context to completely resolve
// all nested obligations. This is because they can inform the
// inference of the impl's type parameters. However, in principle,
// we only need to do this until the impl's type parameters are
// fully bound. It could be a slight optimization to stop
// iterating early.
let
mut
fulfill_cx
=
traits
::
FulfillmentContext
::
new
();
let
vtable
=
selection
.map_move_nested
(|
obligation
|
{
fulfill_cx
.register_obligation
(
tcx
,
obligation
);
});
match
fulfill_cx
.select_all_or_error
(
&
infcx
,
&
param_env
,
&*
unboxed_closures
)
{
Ok
(())
=>
{
}
Err
(
e
)
=>
{
tcx
.sess
.span_bug
(
span
,
format!
(
"Encountered errors `{}` fulfilling `{}` during trans"
,
e
.repr
(
tcx
),
trait_ref
.repr
(
tcx
))
.as_slice
());
}
}
// Use skolemize to simultaneously replace all type variables with
// their bindings and replace all regions with 'static. This is
// sort of overkill because we do not expect there to be any
// unbound type variables, hence no skolemized types should ever
// be inserted.
let
vtable
=
infer
::
skolemize
(
&
infcx
,
vtable
);
info!
(
"Cache miss: {}"
,
trait_ref
.repr
(
ccx
.tcx
()));
ccx
.trait_cache
()
.borrow_mut
()
.insert
(
trait_ref
,
vtable
.clone
());
vtable
}
// Key used to lookup values supplied for type parameters in an expr.
#[deriving(PartialEq)]
pub
enum
ExprOrMethodCall
{
...
...
@@ -778,7 +866,8 @@ pub enum ExprOrMethodCall {
pub
fn
node_id_substs
(
bcx
:
Block
,
node
:
ExprOrMethodCall
)
->
subst
::
Substs
{
->
subst
::
Substs
{
let
tcx
=
bcx
.tcx
();
let
substs
=
match
node
{
...
...
@@ -798,87 +887,10 @@ pub fn node_id_substs(bcx: Block,
substs
.repr
(
bcx
.tcx
()))
.as_slice
());
}
let
substs
=
substs
.erase_regions
();
substs
.substp
(
tcx
,
bcx
.fcx.param_substs
)
}
pub
fn
node_vtables
(
bcx
:
Block
,
id
:
typeck
::
MethodCall
)
->
typeck
::
vtable_res
{
bcx
.tcx
()
.vtable_map
.borrow
()
.find
(
&
id
)
.map
(|
vts
|
{
resolve_vtables_in_fn_ctxt
(
bcx
.fcx
,
vts
)
})
.unwrap_or_else
(||
subst
::
VecPerParamSpace
::
empty
())
}
// Apply the typaram substitutions in the FunctionContext to some
// vtables. This should eliminate any vtable_params.
pub
fn
resolve_vtables_in_fn_ctxt
(
fcx
:
&
FunctionContext
,
vts
:
&
typeck
::
vtable_res
)
->
typeck
::
vtable_res
{
resolve_vtables_under_param_substs
(
fcx
.ccx
.tcx
(),
fcx
.param_substs
,
vts
)
}
pub
fn
resolve_vtables_under_param_substs
(
tcx
:
&
ty
::
ctxt
,
param_substs
:
&
param_substs
,
vts
:
&
typeck
::
vtable_res
)
->
typeck
::
vtable_res
{
vts
.map
(|
ds
|
{
resolve_param_vtables_under_param_substs
(
tcx
,
param_substs
,
ds
)
})
}
pub
fn
resolve_param_vtables_under_param_substs
(
tcx
:
&
ty
::
ctxt
,
param_substs
:
&
param_substs
,
ds
:
&
typeck
::
vtable_param_res
)
->
typeck
::
vtable_param_res
{
ds
.iter
()
.map
(|
d
|
{
resolve_vtable_under_param_substs
(
tcx
,
param_substs
,
d
)
})
.collect
()
}
pub
fn
resolve_vtable_under_param_substs
(
tcx
:
&
ty
::
ctxt
,
param_substs
:
&
param_substs
,
vt
:
&
typeck
::
vtable_origin
)
->
typeck
::
vtable_origin
{
match
*
vt
{
typeck
::
vtable_static
(
trait_id
,
ref
vtable_substs
,
ref
sub
)
=>
{
let
vtable_substs
=
vtable_substs
.substp
(
tcx
,
param_substs
);
typeck
::
vtable_static
(
trait_id
,
vtable_substs
,
resolve_vtables_under_param_substs
(
tcx
,
param_substs
,
sub
))
}
typeck
::
vtable_param
(
n_param
,
n_bound
)
=>
{
find_vtable
(
tcx
,
param_substs
,
n_param
,
n_bound
)
}
typeck
::
vtable_unboxed_closure
(
def_id
)
=>
{
typeck
::
vtable_unboxed_closure
(
def_id
)
}
typeck
::
vtable_error
=>
typeck
::
vtable_error
}
}
pub
fn
find_vtable
(
tcx
:
&
ty
::
ctxt
,
ps
:
&
param_substs
,
n_param
:
typeck
::
param_index
,
n_bound
:
uint
)
->
typeck
::
vtable_origin
{
debug!
(
"find_vtable(n_param={:?}, n_bound={}, ps={})"
,
n_param
,
n_bound
,
ps
.repr
(
tcx
));
let
param_bounds
=
ps
.vtables
.get
(
n_param
.space
,
n_param
.index
);
param_bounds
.get
(
n_bound
)
.clone
()
}
pub
fn
langcall
(
bcx
:
Block
,
span
:
Option
<
Span
>
,
msg
:
&
str
,
...
...
src/librustc/middle/trans/context.rs
浏览文件 @
088c94ae
...
...
@@ -16,6 +16,7 @@
use
llvm
::
mk_target_data
;
use
metadata
::
common
::
LinkMeta
;
use
middle
::
resolve
;
use
middle
::
traits
;
use
middle
::
trans
::
adt
;
use
middle
::
trans
::
base
;
use
middle
::
trans
::
builder
::
Builder
;
...
...
@@ -103,7 +104,7 @@ pub struct LocalCrateContext {
monomorphized
:
RefCell
<
HashMap
<
MonoId
,
ValueRef
>>
,
monomorphizing
:
RefCell
<
DefIdMap
<
uint
>>
,
/// Cache generated vtables
vtables
:
RefCell
<
HashMap
<
(
ty
::
t
,
MonoId
),
ValueRef
>>
,
vtables
:
RefCell
<
HashMap
<
(
ty
::
t
,
Rc
<
ty
::
TraitRef
>
),
ValueRef
>>
,
/// Cache of constant strings,
const_cstr_cache
:
RefCell
<
HashMap
<
InternedString
,
ValueRef
>>
,
...
...
@@ -150,6 +151,9 @@ pub struct LocalCrateContext {
/// This is used to perform some basic load-balancing to keep all LLVM
/// contexts around the same size.
n_llvm_insns
:
Cell
<
uint
>
,
trait_cache
:
RefCell
<
HashMap
<
Rc
<
ty
::
TraitRef
>
,
traits
::
Vtable
<
()
>>>
,
}
pub
struct
CrateContext
<
'a
,
'tcx
:
'a
>
{
...
...
@@ -426,6 +430,7 @@ fn new(shared: &SharedCrateContext,
eh_personality
:
RefCell
::
new
(
None
),
intrinsics
:
RefCell
::
new
(
HashMap
::
new
()),
n_llvm_insns
:
Cell
::
new
(
0u
),
trait_cache
:
RefCell
::
new
(
HashMap
::
new
()),
};
local_ccx
.int_type
=
Type
::
int
(
&
local_ccx
.dummy_ccx
(
shared
));
...
...
@@ -617,7 +622,7 @@ pub fn monomorphizing<'a>(&'a self) -> &'a RefCell<DefIdMap<uint>> {
&
self
.local.monomorphizing
}
pub
fn
vtables
<
'a
>
(
&
'a
self
)
->
&
'a
RefCell
<
HashMap
<
(
ty
::
t
,
MonoId
),
ValueRef
>>
{
pub
fn
vtables
<
'a
>
(
&
'a
self
)
->
&
'a
RefCell
<
HashMap
<
(
ty
::
t
,
Rc
<
ty
::
TraitRef
>
),
ValueRef
>>
{
&
self
.local.vtables
}
...
...
@@ -713,6 +718,10 @@ fn intrinsics<'a>(&'a self) -> &'a RefCell<HashMap<&'static str, ValueRef>> {
pub
fn
count_llvm_insn
(
&
self
)
{
self
.local.n_llvm_insns
.set
(
self
.local.n_llvm_insns
.get
()
+
1
);
}
pub
fn
trait_cache
(
&
self
)
->
&
RefCell
<
HashMap
<
Rc
<
ty
::
TraitRef
>
,
traits
::
Vtable
<
()
>>>
{
&
self
.local.trait_cache
}
}
fn
declare_intrinsic
(
ccx
:
&
CrateContext
,
key
:
&
&
'static
str
)
->
Option
<
ValueRef
>
{
...
...
src/librustc/middle/trans/expr.rs
浏览文件 @
088c94ae
...
...
@@ -41,6 +41,7 @@
use
middle
::
lang_items
::
MallocFnLangItem
;
use
middle
::
mem_categorization
::
Typer
;
use
middle
::
subst
;
use
middle
::
subst
::
Subst
;
use
middle
::
trans
::
_
match
;
use
middle
::
trans
::
adt
;
use
middle
::
trans
::
asm
;
...
...
@@ -78,6 +79,7 @@
use
syntax
::
codemap
;
use
syntax
::
print
::
pprust
::{
expr_to_string
};
use
syntax
::
ptr
::
P
;
use
std
::
rc
::
Rc
;
// Destinations
...
...
@@ -319,10 +321,18 @@ fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
_
=>
bcx
.sess
()
.bug
(
format!
(
"UnsizeStruct with bad sty: {}"
,
bcx
.ty_to_string
(
unsized_ty
))
.as_slice
())
},
&
ty
::
UnsizeVtable
(
..
)
=>
&
ty
::
UnsizeVtable
(
ty
::
TyTrait
{
def_id
:
def_id
,
substs
:
ref
substs
,
..
},
_
)
=>
{
let
substs
=
substs
.with_self_ty
(
unsized_ty
);
let
trait_ref
=
Rc
::
new
(
ty
::
TraitRef
{
def_id
:
def_id
,
substs
:
substs
});
let
trait_ref
=
trait_ref
.subst
(
bcx
.tcx
(),
&
bcx
.fcx.param_substs.substs
);
let
box_ty
=
mk_ty
(
unsized_ty
);
PointerCast
(
bcx
,
meth
::
vtable_ptr
(
bcx
,
id
,
mk_ty
(
unsized_ty
)
),
meth
::
get_vtable
(
bcx
,
box_ty
,
trait_ref
),
Type
::
vtable_ptr
(
bcx
.ccx
()))
}
}
}
...
...
@@ -1052,8 +1062,16 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
ast
::
ExprCast
(
ref
val
,
_
)
=>
{
// DPS output mode means this is a trait cast:
if
ty
::
type_is_trait
(
node_id_type
(
bcx
,
expr
.id
))
{
let
trait_ref
=
bcx
.tcx
()
.object_cast_map
.borrow
()
.find
(
&
expr
.id
)
.map
(|
t
|
(
*
t
)
.clone
())
.unwrap
();
let
trait_ref
=
trait_ref
.subst
(
bcx
.tcx
(),
&
bcx
.fcx.param_substs.substs
);
let
datum
=
unpack_datum!
(
bcx
,
trans
(
bcx
,
&**
val
));
meth
::
trans_trait_cast
(
bcx
,
datum
,
expr
.id
,
dest
)
meth
::
trans_trait_cast
(
bcx
,
datum
,
expr
.id
,
trait_ref
,
dest
)
}
else
{
bcx
.tcx
()
.sess
.span_bug
(
expr
.span
,
"expr_cast of non-trait"
);
...
...
src/librustc/middle/trans/meth.rs
浏览文件 @
088c94ae
此差异已折叠。
点击以展开。
src/librustc/middle/trans/monomorphize.rs
浏览文件 @
088c94ae
...
...
@@ -34,17 +34,14 @@
pub
fn
monomorphic_fn
(
ccx
:
&
CrateContext
,
fn_id
:
ast
::
DefId
,
real_substs
:
&
subst
::
Substs
,
vtables
:
typeck
::
vtable_res
,
ref_id
:
Option
<
ast
::
NodeId
>
)
->
(
ValueRef
,
bool
)
{
debug!
(
"monomorphic_fn(
\
fn_id={},
\
real_substs={},
\
vtables={},
\
ref_id={:?})"
,
fn_id
.repr
(
ccx
.tcx
()),
real_substs
.repr
(
ccx
.tcx
()),
vtables
.repr
(
ccx
.tcx
()),
ref_id
);
assert
!
(
real_substs
.types
.all
(|
t
|
{
...
...
@@ -69,7 +66,6 @@ pub fn monomorphic_fn(ccx: &CrateContext,
let
psubsts
=
param_substs
{
substs
:
(
*
real_substs
)
.clone
(),
vtables
:
vtables
,
};
debug!
(
"monomorphic_fn(
\
...
...
@@ -286,7 +282,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
(
lldecl
,
true
)
}
// Used to identify cached monomorphized functions
and vtables
// Used to identify cached monomorphized functions
#[deriving(PartialEq,
Eq,
Hash)]
pub
struct
MonoParamId
{
pub
subst
:
ty
::
t
,
...
...
src/librustc/middle/ty.rs
浏览文件 @
088c94ae
...
...
@@ -28,6 +28,7 @@
use
middle
::
stability
;
use
middle
::
subst
::{
Subst
,
Substs
,
VecPerParamSpace
};
use
middle
::
subst
;
use
middle
::
traits
;
use
middle
::
ty
;
use
middle
::
typeck
;
use
middle
::
ty_fold
;
...
...
@@ -272,9 +273,7 @@ pub enum UnsizeKind {
// An unsize coercion applied to the tail field of a struct.
// The uint is the index of the type parameter which is unsized.
UnsizeStruct
(
Box
<
UnsizeKind
>
,
uint
),
UnsizeVtable
(
ty
::
ExistentialBounds
,
ast
::
DefId
,
/* Trait ID */
subst
::
Substs
/* Trait substitutions */
)
UnsizeVtable
(
TyTrait
,
/* the self type of the trait */
ty
::
t
)
}
#[deriving(Clone)]
...
...
@@ -365,13 +364,13 @@ pub fn type_of_adjust(cx: &ctxt, adj: &AutoAdjustment) -> Option<t> {
fn
type_of_autoref
(
cx
:
&
ctxt
,
autoref
:
&
AutoRef
)
->
Option
<
t
>
{
match
autoref
{
&
AutoUnsize
(
ref
k
)
=>
match
k
{
&
UnsizeVtable
(
bounds
,
def_id
,
ref
substs
)
=>
{
&
UnsizeVtable
(
TyTrait
{
def_id
,
substs
:
ref
substs
,
bounds
},
_
)
=>
{
Some
(
mk_trait
(
cx
,
def_id
,
substs
.clone
(),
bounds
))
}
_
=>
None
},
&
AutoUnsizeUniq
(
ref
k
)
=>
match
k
{
&
UnsizeVtable
(
bounds
,
def_id
,
ref
substs
)
=>
{
&
UnsizeVtable
(
TyTrait
{
def_id
,
substs
:
ref
substs
,
bounds
},
_
)
=>
{
Some
(
mk_uniq
(
cx
,
mk_trait
(
cx
,
def_id
,
substs
.clone
(),
bounds
)))
}
_
=>
None
...
...
@@ -458,6 +457,10 @@ pub struct ctxt<'tcx> {
pub
trait_refs
:
RefCell
<
NodeMap
<
Rc
<
TraitRef
>>>
,
pub
trait_defs
:
RefCell
<
DefIdMap
<
Rc
<
TraitDef
>>>
,
/// Maps from node-id of a trait object cast (like `foo as
/// Box<Trait>`) to the trait reference.
pub
object_cast_map
:
typeck
::
ObjectCastMap
,
pub
map
:
ast_map
::
Map
<
'tcx
>
,
pub
intrinsic_defs
:
RefCell
<
DefIdMap
<
t
>>
,
pub
freevars
:
RefCell
<
freevars
::
freevar_map
>
,
...
...
@@ -499,7 +502,7 @@ pub struct ctxt<'tcx> {
/// Maps a DefId of a type to a list of its inherent impls.
/// Contains implementations of methods that are inherent to a type.
/// Methods in these implementations don't need to be exported.
pub
inherent_impls
:
RefCell
<
DefIdMap
<
Rc
<
RefCell
<
Vec
<
ast
::
DefId
>
>>>>
,
pub
inherent_impls
:
RefCell
<
DefIdMap
<
Rc
<
Vec
<
ast
::
DefId
>>>>
,
/// Maps a DefId of an impl to a list of its items.
/// Note that this contains all of the impls that we know about,
...
...
@@ -516,9 +519,6 @@ pub struct ctxt<'tcx> {
/// about.
pub
used_mut_nodes
:
RefCell
<
NodeSet
>
,
/// vtable resolution information for impl declarations
pub
impl_vtables
:
typeck
::
impl_vtable_map
,
/// The set of external nominal types whose implementations have been read.
/// This is used for lazy resolution of methods.
pub
populated_external_types
:
RefCell
<
DefIdSet
>
,
...
...
@@ -536,7 +536,6 @@ pub struct ctxt<'tcx> {
pub
extern_const_variants
:
RefCell
<
DefIdMap
<
ast
::
NodeId
>>
,
pub
method_map
:
typeck
::
MethodMap
,
pub
vtable_map
:
typeck
::
vtable_map
,
pub
dependency_formats
:
RefCell
<
dependency_format
::
Dependencies
>
,
...
...
@@ -1435,6 +1434,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
item_substs
:
RefCell
::
new
(
NodeMap
::
new
()),
trait_refs
:
RefCell
::
new
(
NodeMap
::
new
()),
trait_defs
:
RefCell
::
new
(
DefIdMap
::
new
()),
object_cast_map
:
RefCell
::
new
(
NodeMap
::
new
()),
map
:
map
,
intrinsic_defs
:
RefCell
::
new
(
DefIdMap
::
new
()),
freevars
:
RefCell
::
new
(
freevars
),
...
...
@@ -1463,14 +1463,12 @@ pub fn mk_ctxt<'tcx>(s: Session,
impl_items
:
RefCell
::
new
(
DefIdMap
::
new
()),
used_unsafe
:
RefCell
::
new
(
NodeSet
::
new
()),
used_mut_nodes
:
RefCell
::
new
(
NodeSet
::
new
()),
impl_vtables
:
RefCell
::
new
(
DefIdMap
::
new
()),
populated_external_types
:
RefCell
::
new
(
DefIdSet
::
new
()),
populated_external_traits
:
RefCell
::
new
(
DefIdSet
::
new
()),
upvar_borrow_map
:
RefCell
::
new
(
HashMap
::
new
()),
extern_const_statics
:
RefCell
::
new
(
DefIdMap
::
new
()),
extern_const_variants
:
RefCell
::
new
(
DefIdMap
::
new
()),
method_map
:
RefCell
::
new
(
FnvHashMap
::
new
()),
vtable_map
:
RefCell
::
new
(
FnvHashMap
::
new
()),
dependency_formats
:
RefCell
::
new
(
HashMap
::
new
()),
unboxed_closures
:
RefCell
::
new
(
DefIdMap
::
new
()),
node_lint_levels
:
RefCell
::
new
(
HashMap
::
new
()),
...
...
@@ -2944,13 +2942,17 @@ fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
}
pub
fn
type_is_trait
(
ty
:
t
)
->
bool
{
type_trait_info
(
ty
)
.is_some
()
}
pub
fn
type_trait_info
(
ty
:
t
)
->
Option
<&
'static
TyTrait
>
{
match
get
(
ty
)
.sty
{
ty_uniq
(
ty
)
|
ty_rptr
(
_
,
mt
{
ty
,
..
})
|
ty_ptr
(
mt
{
ty
,
..
})
=>
match
get
(
ty
)
.sty
{
ty_trait
(
..
)
=>
true
,
_
=>
fals
e
ty_trait
(
ref
t
)
=>
Some
(
&**
t
)
,
_
=>
Non
e
},
ty_trait
(
..
)
=>
true
,
_
=>
fals
e
ty_trait
(
ref
t
)
=>
Some
(
&**
t
)
,
_
=>
Non
e
}
}
...
...
@@ -3491,7 +3493,7 @@ pub fn unsize_ty(cx: &ctxt,
format!
(
"UnsizeStruct with bad sty: {}"
,
ty_to_string
(
cx
,
ty
))
.as_slice
())
},
&
UnsizeVtable
(
bounds
,
def_id
,
ref
substs
)
=>
{
&
UnsizeVtable
(
TyTrait
{
def_id
,
substs
:
ref
substs
,
bounds
},
_
)
=>
{
mk_trait
(
cx
,
def_id
,
substs
.clone
(),
bounds
)
}
}
...
...
@@ -3511,10 +3513,10 @@ pub fn map_region(&self, f: |Region| -> Region) -> AutoRef {
}
pub
fn
method_call_type_param_defs
<
'tcx
,
T
>
(
typer
:
&
T
,
origin
:
typeck
::
MethodOrigin
)
origin
:
&
typeck
::
MethodOrigin
)
->
VecPerParamSpace
<
TypeParameterDef
>
where
T
:
mc
::
Typer
<
'tcx
>
{
match
origin
{
match
*
origin
{
typeck
::
MethodStatic
(
did
)
=>
{
ty
::
lookup_item_type
(
typer
.tcx
(),
did
)
.generics.types
.clone
()
}
...
...
@@ -3529,16 +3531,16 @@ pub fn method_call_type_param_defs<'tcx, T>(typer: &T,
lookup_trait_def
(
typer
.tcx
(),
def_id
)
.generics.types
.clone
()
}
typeck
::
MethodParam
(
typeck
::
MethodParam
{
trait_
id
:
trt_id
,
trait_
ref
:
ref
trait_ref
,
method_num
:
n_mth
,
..
})
|
typeck
::
MethodObject
(
typeck
::
MethodObject
{
trait_
id
:
trt_id
,
trait_
ref
:
ref
trait_ref
,
method_num
:
n_mth
,
..
})
=>
{
match
ty
::
trait_item
(
typer
.tcx
(),
tr
t
_id
,
n_mth
)
{
match
ty
::
trait_item
(
typer
.tcx
(),
tr
ait_ref
.def
_id
,
n_mth
)
{
ty
::
MethodTraitItem
(
method
)
=>
method
.generics.types
.clone
(),
}
}
...
...
@@ -4407,14 +4409,6 @@ pub fn lookup_item_type(cx: &ctxt,
||
csearch
::
get_type
(
cx
,
did
))
}
pub
fn
lookup_impl_vtables
(
cx
:
&
ctxt
,
did
:
ast
::
DefId
)
->
typeck
::
vtable_res
{
lookup_locally_or_in_crate_store
(
"impl_vtables"
,
did
,
&
mut
*
cx
.impl_vtables
.borrow_mut
(),
||
csearch
::
get_impl_vtables
(
cx
,
did
)
)
}
/// Given the did of a trait, returns its canonical trait ref.
pub
fn
lookup_trait_def
(
cx
:
&
ctxt
,
did
:
ast
::
DefId
)
->
Rc
<
ty
::
TraitDef
>
{
let
mut
trait_defs
=
cx
.trait_defs
.borrow_mut
();
...
...
@@ -4958,6 +4952,7 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
return
}
let
mut
inherent_impls
=
Vec
::
new
();
csearch
::
each_implementation_for_type
(
&
tcx
.sess.cstore
,
type_id
,
|
impl_def_id
|
{
let
impl_items
=
csearch
::
get_impl_items
(
&
tcx
.sess.cstore
,
...
...
@@ -4989,18 +4984,11 @@ pub fn populate_implementations_for_type_if_necessary(tcx: &ctxt,
// If this is an inherent implementation, record it.
if
associated_traits
.is_none
()
{
match
tcx
.inherent_impls
.borrow
()
.find
(
&
type_id
)
{
Some
(
implementation_list
)
=>
{
implementation_list
.borrow_mut
()
.push
(
impl_def_id
);
return
;
}
None
=>
{}
}
tcx
.inherent_impls
.borrow_mut
()
.insert
(
type_id
,
Rc
::
new
(
RefCell
::
new
(
vec!
(
impl_def_id
))));
inherent_impls
.push
(
impl_def_id
);
}
});
tcx
.inherent_impls
.borrow_mut
()
.insert
(
type_id
,
Rc
::
new
(
inherent_impls
));
tcx
.populated_external_types
.borrow_mut
()
.insert
(
type_id
);
}
...
...
@@ -5232,7 +5220,7 @@ pub fn hash_crate_independent(tcx: &ctxt, t: t, svh: &Svh) -> u64 {
}
}
}
ty_trait
(
box
ty
::
TyTrait
{
def_id
:
d
,
bounds
,
..
})
=>
{
ty_trait
(
box
TyTrait
{
def_id
:
d
,
bounds
,
..
})
=>
{
byte!
(
17
);
did
(
&
mut
state
,
d
);
hash!
(
bounds
);
...
...
@@ -5430,6 +5418,26 @@ pub fn from_mutbl(m: ast::Mutability) -> BorrowKind {
}
}
pub
fn
to_mutbl_lossy
(
self
)
->
ast
::
Mutability
{
/*!
* Returns a mutability `m` such that an `&m T` pointer could
* be used to obtain this borrow kind. Because borrow kinds
* are richer than mutabilities, we sometimes have to pick a
* mutability that is stornger than necessary so that it at
* least *would permit* the borrow in question.
*/
match
self
{
MutBorrow
=>
ast
::
MutMutable
,
ImmBorrow
=>
ast
::
MutImmutable
,
// We have no type correponding to a unique imm borrow, so
// use `&mut`. It gives all the capabilities of an `&uniq`
// and hence is a safe "over approximation".
UniqueImmBorrow
=>
ast
::
MutMutable
,
}
}
pub
fn
to_user_str
(
&
self
)
->
&
'static
str
{
match
*
self
{
MutBorrow
=>
"mutable"
,
...
...
src/librustc/middle/ty_fold.rs
浏览文件 @
088c94ae
...
...
@@ -680,3 +680,28 @@ fn fold_region(&mut self, r: ty::Region) -> ty::Region {
}
}
}
///////////////////////////////////////////////////////////////////////////
// Region eraser
//
// Replaces all free regions with 'static. Useful in trans.
pub
struct
RegionEraser
<
'a
,
'tcx
:
'a
>
{
tcx
:
&
'a
ty
::
ctxt
<
'tcx
>
,
}
pub
fn
erase_regions
<
T
:
TypeFoldable
>
(
tcx
:
&
ty
::
ctxt
,
t
:
T
)
->
T
{
let
mut
eraser
=
RegionEraser
{
tcx
:
tcx
};
t
.fold_with
(
&
mut
eraser
)
}
impl
<
'a
,
'tcx
>
TypeFolder
<
'tcx
>
for
RegionEraser
<
'a
,
'tcx
>
{
fn
tcx
<
'a
>
(
&
'a
self
)
->
&
'a
ty
::
ctxt
<
'tcx
>
{
self
.tcx
}
fn
fold_region
(
&
mut
self
,
r
:
ty
::
Region
)
->
ty
::
Region
{
match
r
{
ty
::
ReLateBound
(
..
)
|
ty
::
ReEarlyBound
(
..
)
=>
r
,
_
=>
ty
::
ReStatic
}
}
}
src/librustc/middle/typeck/infer/coercion.rs
浏览文件 @
088c94ae
...
...
@@ -370,7 +370,7 @@ fn coerce_unsized(&self,
}
(
&
ty
::
ty_uniq
(
t_a
),
&
ty
::
ty_uniq
(
t_b
))
=>
{
self
.unpack_actual_value
(
t_a
,
|
sty_a
|
{
match
self
.unsize_ty
(
sty_a
,
t_b
)
{
match
self
.unsize_ty
(
t_a
,
sty_a
,
t_b
)
{
Some
((
ty
,
kind
))
=>
{
let
ty
=
ty
::
mk_uniq
(
self
.get_ref
()
.infcx.tcx
,
ty
);
try!
(
self
.get_ref
()
.infcx
.try
(||
sub
.tys
(
ty
,
b
)));
...
...
@@ -393,6 +393,7 @@ fn coerce_unsized(&self,
// performed to unsize it.
// E.g., `[T, ..n]` -> `([T], UnsizeLength(n))`
fn
unsize_ty
(
&
self
,
ty_a
:
ty
::
t
,
sty_a
:
&
ty
::
sty
,
ty_b
:
ty
::
t
)
->
Option
<
(
ty
::
t
,
ty
::
UnsizeKind
)
>
{
...
...
@@ -412,9 +413,10 @@ fn unsize_ty(&self,
def_id
,
substs
.clone
(),
bounds
);
Some
((
ty
,
ty
::
UnsizeVtable
(
bounds
,
def_id
,
substs
.clone
())))
Some
((
ty
,
ty
::
UnsizeVtable
(
ty
::
TyTrait
{
def_id
:
def_id
,
bounds
:
bounds
,
substs
:
substs
.clone
()
},
ty_a
)))
}
(
&
ty
::
ty_struct
(
did_a
,
ref
substs_a
),
&
ty
::
ty_struct
(
did_b
,
ref
substs_b
))
if
did_a
==
did_b
=>
{
...
...
@@ -432,7 +434,11 @@ fn unsize_ty(&self,
if
self
.get_ref
()
.infcx
.try
(||
sub
.tys
(
*
tp_a
,
*
tp_b
))
.is_ok
()
{
continue
;
}
match
self
.unpack_actual_value
(
*
tp_a
,
|
tp
|
self
.unsize_ty
(
tp
,
*
tp_b
))
{
match
self
.unpack_actual_value
(
*
tp_a
,
|
tp
|
self
.unsize_ty
(
*
tp_a
,
tp
,
*
tp_b
))
{
Some
((
new_tp
,
k
))
=>
{
// Check that the whole types match.
let
mut
new_substs
=
substs_a
.clone
();
...
...
@@ -471,14 +477,14 @@ fn coerce_borrowed_object(&self,
{
let
tcx
=
self
.get_ref
()
.infcx.tcx
;
debug!
(
"coerce_borrowed_object(a={}, sty_a={:?}, b={})"
,
debug!
(
"coerce_borrowed_object(a={}, sty_a={:?}, b={}
, b_mutbl={}
)"
,
a
.repr
(
tcx
),
sty_a
,
b
.repr
(
tcx
));
b
.repr
(
tcx
)
,
b_mutbl
);
let
coercion
=
Coercion
(
self
.get_ref
()
.trace
.clone
());
let
r_a
=
self
.get_ref
()
.infcx
.next_region_var
(
coercion
);
self
.coerce_object
(
a
,
sty_a
,
b
,
self
.coerce_object
(
a
,
sty_a
,
b
,
b_mutbl
,
|
tr
|
ty
::
mk_rptr
(
tcx
,
r_a
,
ty
::
mt
{
mutbl
:
b_mutbl
,
ty
:
tr
}),
||
AutoPtr
(
r_a
,
b_mutbl
,
None
))
}
...
...
@@ -491,11 +497,11 @@ fn coerce_unsafe_object(&self,
{
let
tcx
=
self
.get_ref
()
.infcx.tcx
;
debug!
(
"coerce_unsafe_object(a={}, sty_a={:?}, b={})"
,
debug!
(
"coerce_unsafe_object(a={}, sty_a={:?}, b={}
, b_mutbl={}
)"
,
a
.repr
(
tcx
),
sty_a
,
b
.repr
(
tcx
));
b
.repr
(
tcx
)
,
b_mutbl
);
self
.coerce_object
(
a
,
sty_a
,
b
,
self
.coerce_object
(
a
,
sty_a
,
b
,
b_mutbl
,
|
tr
|
ty
::
mk_ptr
(
tcx
,
ty
::
mt
{
mutbl
:
b_mutbl
,
ty
:
tr
}),
||
AutoUnsafe
(
b_mutbl
,
None
))
}
...
...
src/librustc/middle/typeck/infer/combine.rs
浏览文件 @
088c94ae
...
...
@@ -34,7 +34,7 @@
use
middle
::
subst
;
use
middle
::
subst
::
Substs
;
use
middle
::
subst
::
{
ErasedRegions
,
NonerasedRegions
,
Substs
}
;
use
middle
::
ty
::{
FloatVar
,
FnSig
,
IntVar
,
TyVar
};
use
middle
::
ty
::{
IntType
,
UintType
};
use
middle
::
ty
::{
BuiltinBounds
};
...
...
@@ -113,29 +113,40 @@ fn substs(&self,
let
a_tps
=
a_subst
.types
.get_slice
(
space
);
let
b_tps
=
b_subst
.types
.get_slice
(
space
);
let
tps
=
try!
(
self
.tps
(
space
,
a_tps
,
b_tps
));
substs
.types
.replace
(
space
,
tps
);
}
let
a_regions
=
a_subst
.regions
()
.get_slice
(
space
);
let
b_regions
=
b_subst
.regions
()
.get_slice
(
space
);
let
mut
invariance
=
Vec
::
new
();
let
r_variances
=
match
variances
{
Some
(
ref
variances
)
=>
variances
.regions
.get_slice
(
space
),
None
=>
{
for
_
in
a_regions
.iter
()
{
invariance
.push
(
ty
::
Invariant
);
}
invariance
.as_slice
()
}
};
match
(
&
a_subst
.regions
,
&
b_subst
.regions
)
{
(
&
ErasedRegions
,
_
)
|
(
_
,
&
ErasedRegions
)
=>
{
substs
.regions
=
ErasedRegions
;
}
let
regions
=
try!
(
relate_region_params
(
self
,
item_def_id
,
r_variances
,
a_regions
,
b_regions
));
(
&
NonerasedRegions
(
ref
a
),
&
NonerasedRegions
(
ref
b
))
=>
{
for
&
space
in
subst
::
ParamSpace
::
all
()
.iter
()
{
let
a_regions
=
a
.get_slice
(
space
);
let
b_regions
=
b
.get_slice
(
space
);
substs
.types
.replace
(
space
,
tps
);
substs
.mut_regions
()
.replace
(
space
,
regions
);
let
mut
invariance
=
Vec
::
new
();
let
r_variances
=
match
variances
{
Some
(
ref
variances
)
=>
{
variances
.regions
.get_slice
(
space
)
}
None
=>
{
for
_
in
a_regions
.iter
()
{
invariance
.push
(
ty
::
Invariant
);
}
invariance
.as_slice
()
}
};
let
regions
=
try!
(
relate_region_params
(
self
,
item_def_id
,
r_variances
,
a_regions
,
b_regions
));
substs
.mut_regions
()
.replace
(
space
,
regions
);
}
}
}
return
Ok
(
substs
);
...
...
src/librustc/middle/typeck/mod.rs
浏览文件 @
088c94ae
...
...
@@ -71,9 +71,10 @@
use
util
::
common
::
time
;
use
util
::
ppaux
::
Repr
;
use
util
::
ppaux
;
use
util
::
nodemap
::{
DefId
Map
,
FnvHashMap
};
use
util
::
nodemap
::{
Node
Map
,
FnvHashMap
};
use
std
::
cell
::
RefCell
;
use
std
::
rc
::
Rc
;
use
syntax
::
codemap
::
Span
;
use
syntax
::
print
::
pprust
::
*
;
use
syntax
::{
ast
,
ast_map
,
abi
};
...
...
@@ -92,7 +93,7 @@ pub struct param_index {
pub
index
:
uint
}
#[deriving(Clone
,
Encodable,
Decodable
)]
#[deriving(Clone)]
pub
enum
MethodOrigin
{
// fully statically resolved method
MethodStatic
(
ast
::
DefId
),
...
...
@@ -110,27 +111,21 @@ pub enum MethodOrigin {
// details for a method invoked with a receiver whose type is a type parameter
// with a bounded trait.
#[deriving(Clone
,
Encodable,
Decodable
)]
#[deriving(Clone)]
pub
struct
MethodParam
{
// the trait containing the method to be invoked
pub
trait_id
:
ast
::
DefId
,
// the precise trait reference that occurs as a bound -- this may
// be a supertrait of what the user actually typed.
pub
trait_ref
:
Rc
<
ty
::
TraitRef
>
,
// index of
the method to be invoked amongst the trait's methods
// index of
uint in the list of methods for the trait
pub
method_num
:
uint
,
// index of the type parameter (from those that are in scope) that is
// the type of the receiver
pub
param_num
:
param_index
,
// index of the bound for this type parameter which specifies the trait
pub
bound_num
:
uint
,
}
// details for a method invoked with a receiver whose type is an object
#[deriving(Clone
,
Encodable,
Decodable
)]
#[deriving(Clone)]
pub
struct
MethodObject
{
// the (super)trait containing the method to be invoked
pub
trait_
id
:
ast
::
DefId
,
pub
trait_
ref
:
Rc
<
ty
::
TraitRef
>
,
// the actual base trait id of the object
pub
object_trait_id
:
ast
::
DefId
,
...
...
@@ -154,7 +149,7 @@ pub struct MethodCallee {
/**
* With method calls, we store some extra information in
* side tables (i.e method_map
, vtable_map
). We use
* side tables (i.e method_map). We use
* MethodCall as a key to index into these tables instead of
* just directly using the expression's NodeId. The reason
* for this being that we may apply adjustments (coercions)
...
...
@@ -276,10 +271,9 @@ fn repr(&self, tcx: &ty::ctxt) -> String {
}
}
pub
type
vtable_map
=
RefCell
<
FnvHashMap
<
MethodCall
,
vtable_res
>>
;
pub
type
impl_vtable_map
=
RefCell
<
DefIdMap
<
vtable_res
>>
;
// For every explicit cast into an object type, maps from the cast
// expr to the associated trait ref.
pub
type
ObjectCastMap
=
RefCell
<
NodeMap
<
Rc
<
ty
::
TraitRef
>>>
;
pub
struct
CrateCtxt
<
'a
,
'tcx
:
'a
>
{
// A mapping from method call sites to traits that have that method.
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录