Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
85970d49
R
Rust
项目概览
int
/
Rust
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
85970d49
编写于
12月 04, 2014
作者:
H
Huon Wilson
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Intern Region in tcx.
This makes sty only 32 bytes on machines with 64-bit pointers.
上级
add6bb2f
变更
20
隐藏空白更改
内联
并排
Showing
20 changed file
with
93 addition
and
71 deletion
+93
-71
src/librustc/metadata/tydecode.rs
src/librustc/metadata/tydecode.rs
+3
-2
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/expr_use_visitor.rs
+1
-1
src/librustc/middle/infer/coercion.rs
src/librustc/middle/infer/coercion.rs
+4
-3
src/librustc/middle/infer/combine.rs
src/librustc/middle/infer/combine.rs
+4
-4
src/librustc/middle/mem_categorization.rs
src/librustc/middle/mem_categorization.rs
+2
-2
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+36
-21
src/librustc/util/ppaux.rs
src/librustc/util/ppaux.rs
+1
-1
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/_match.rs
+4
-2
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/base.rs
+4
-4
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/expr.rs
+1
-1
src/librustc_typeck/astconv.rs
src/librustc_typeck/astconv.rs
+3
-3
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/_match.rs
+4
-4
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/closure.rs
+1
-1
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/method/mod.rs
+1
-1
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/method/probe.rs
+1
-1
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/mod.rs
+10
-7
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/regionck.rs
+8
-8
src/librustc_typeck/check/regionmanip.rs
src/librustc_typeck/check/regionmanip.rs
+2
-2
src/librustc_typeck/check/vtable.rs
src/librustc_typeck/check/vtable.rs
+2
-2
src/librustc_typeck/variance.rs
src/librustc_typeck/variance.rs
+1
-1
未找到文件。
src/librustc/metadata/tydecode.rs
浏览文件 @
85970d49
...
...
@@ -432,7 +432,7 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
'&'
=>
{
let
r
=
parse_region
(
st
,
|
x
,
y
|
conv
(
x
,
y
));
let
mt
=
parse_mt
(
st
,
|
x
,
y
|
conv
(
x
,
y
));
return
ty
::
mk_rptr
(
st
.tcx
,
r
,
mt
);
return
ty
::
mk_rptr
(
st
.tcx
,
st
.tcx
.mk_region
(
r
)
,
mt
);
}
'V'
=>
{
let
t
=
parse_ty
(
st
,
|
x
,
y
|
conv
(
x
,
y
));
...
...
@@ -500,7 +500,8 @@ fn parse_ty<'a, 'tcx>(st: &mut PState<'a, 'tcx>, conv: conv_did) -> Ty<'tcx> {
let
region
=
parse_region
(
st
,
|
x
,
y
|
conv
(
x
,
y
));
let
substs
=
parse_substs
(
st
,
|
x
,
y
|
conv
(
x
,
y
));
assert_eq!
(
next
(
st
),
']'
);
return
ty
::
mk_unboxed_closure
(
st
.tcx
,
did
,
region
,
st
.tcx
.mk_substs
(
substs
));
return
ty
::
mk_unboxed_closure
(
st
.tcx
,
did
,
st
.tcx
.mk_region
(
region
),
st
.tcx
.mk_substs
(
substs
));
}
'e'
=>
{
return
ty
::
mk_err
();
...
...
src/librustc/middle/expr_use_visitor.rs
浏览文件 @
85970d49
...
...
@@ -861,7 +861,7 @@ fn walk_autoderefs(&mut self,
};
let
bk
=
ty
::
BorrowKind
::
from_mutbl
(
m
);
self
.delegate
.borrow
(
expr
.id
,
expr
.span
,
cmt
,
r
,
bk
,
AutoRef
);
*
r
,
bk
,
AutoRef
);
}
}
}
...
...
src/librustc/middle/infer/coercion.rs
浏览文件 @
85970d49
...
...
@@ -230,7 +230,7 @@ pub fn coerce_borrowed_pointer(&self,
};
let
a_borrowed
=
ty
::
mk_rptr
(
self
.tcx
(),
r_borrow
,
self
.tcx
()
.mk_region
(
r_borrow
)
,
mt
{
ty
:
inner_ty
,
mutbl
:
mutbl_b
});
try!
(
sub
.tys
(
a_borrowed
,
b
));
...
...
@@ -271,7 +271,7 @@ fn coerce_unsized(&self,
let
coercion
=
Coercion
(
self
.get_ref
()
.trace
.clone
());
let
r_borrow
=
self
.get_ref
()
.infcx
.next_region_var
(
coercion
);
let
ty
=
ty
::
mk_rptr
(
self
.tcx
(),
r_borrow
,
self
.tcx
()
.mk_region
(
r_borrow
)
,
ty
::
mt
{
ty
:
ty
,
mutbl
:
mt_b
.mutbl
});
try!
(
self
.get_ref
()
.infcx
.try
(|
_
|
sub
.tys
(
ty
,
b
)));
debug!
(
"Success, coerced with AutoDerefRef(1,
\
...
...
@@ -424,7 +424,8 @@ fn coerce_borrowed_object(&self,
let
r_a
=
self
.get_ref
()
.infcx
.next_region_var
(
coercion
);
self
.coerce_object
(
a
,
b
,
b_mutbl
,
|
tr
|
ty
::
mk_rptr
(
tcx
,
r_a
,
ty
::
mt
{
mutbl
:
b_mutbl
,
ty
:
tr
}),
|
tr
|
ty
::
mk_rptr
(
tcx
,
tcx
.mk_region
(
r_a
),
ty
::
mt
{
mutbl
:
b_mutbl
,
ty
:
tr
}),
||
AutoPtr
(
r_a
,
b_mutbl
,
None
))
}
...
...
src/librustc/middle/infer/combine.rs
浏览文件 @
85970d49
...
...
@@ -499,9 +499,9 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
// All ty_unboxed_closure types with the same id represent
// the (anonymous) type of the same closure expression. So
// all of their regions should be equated.
let
region
=
try!
(
this
.equate
()
.regions
(
a_region
,
b_region
));
let
region
=
try!
(
this
.equate
()
.regions
(
*
a_region
,
*
b_region
));
let
substs
=
try!
(
this
.substs_variances
(
None
,
a_substs
,
b_substs
));
Ok
(
ty
::
mk_unboxed_closure
(
tcx
,
a_id
,
region
,
tcx
.mk_substs
(
substs
)))
Ok
(
ty
::
mk_unboxed_closure
(
tcx
,
a_id
,
tcx
.mk_region
(
region
)
,
tcx
.mk_substs
(
substs
)))
}
(
&
ty
::
ty_uniq
(
a_inner
),
&
ty
::
ty_uniq
(
b_inner
))
=>
{
...
...
@@ -515,7 +515,7 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
}
(
&
ty
::
ty_rptr
(
a_r
,
ref
a_mt
),
&
ty
::
ty_rptr
(
b_r
,
ref
b_mt
))
=>
{
let
r
=
try!
(
this
.contraregions
(
a_r
,
b_r
));
let
r
=
try!
(
this
.contraregions
(
*
a_r
,
*
b_r
));
// FIXME(14985) If we have mutable references to trait objects, we
// used to use covariant subtyping. I have preserved this behaviour,
// even though it is probably incorrect. So don't go down the usual
...
...
@@ -527,7 +527,7 @@ pub fn super_tys<'tcx, C: Combine<'tcx>>(this: &C,
}
_
=>
try!
(
this
.mts
(
a_mt
,
b_mt
))
};
Ok
(
ty
::
mk_rptr
(
tcx
,
r
,
mt
))
Ok
(
ty
::
mk_rptr
(
tcx
,
tcx
.mk_region
(
r
)
,
mt
))
}
(
&
ty
::
ty_vec
(
a_t
,
Some
(
sz_a
)),
&
ty
::
ty_vec
(
b_t
,
Some
(
sz_b
)))
=>
{
...
...
src/librustc/middle/mem_categorization.rs
浏览文件 @
85970d49
...
...
@@ -204,7 +204,7 @@ pub fn opt_deref_kind(t: Ty) -> Option<deref_kind> {
ty
::
ty_rptr
(
r
,
mt
)
=>
{
let
kind
=
ty
::
BorrowKind
::
from_mutbl
(
mt
.mutbl
);
Some
(
deref_ptr
(
BorrowedPtr
(
kind
,
r
)))
Some
(
deref_ptr
(
BorrowedPtr
(
kind
,
*
r
)))
}
ty
::
ty_closure
(
box
ty
::
ClosureTy
{
...
...
@@ -1071,7 +1071,7 @@ fn vec_slice_info(tcx: &ty::ctxt,
->
(
ast
::
Mutability
,
ty
::
Region
)
{
match
slice_ty
.sty
{
ty
::
ty_rptr
(
r
,
ref
mt
)
=>
match
mt
.ty.sty
{
ty
::
ty_vec
(
_
,
None
)
=>
(
mt
.mutbl
,
r
),
ty
::
ty_vec
(
_
,
None
)
=>
(
mt
.mutbl
,
*
r
),
_
=>
vec_slice_info
(
tcx
,
pat
,
mt
.ty
),
},
...
...
src/librustc/middle/ty.rs
浏览文件 @
85970d49
...
...
@@ -410,7 +410,7 @@ fn type_of_autoref<'tcx>(cx: &ctxt<'tcx>, autoref: &AutoRef<'tcx>) -> Option<Ty<
},
&
AutoPtr
(
r
,
m
,
Some
(
box
ref
autoref
))
=>
{
match
type_of_autoref
(
cx
,
autoref
)
{
Some
(
ty
)
=>
Some
(
mk_rptr
(
cx
,
r
,
mt
{
mutbl
:
m
,
ty
:
ty
})),
Some
(
ty
)
=>
Some
(
mk_rptr
(
cx
,
cx
.mk_region
(
r
)
,
mt
{
mutbl
:
m
,
ty
:
ty
})),
None
=>
None
}
}
...
...
@@ -609,6 +609,7 @@ pub struct CtxtArenas<'tcx> {
type_
:
TypedArena
<
TyS
<
'tcx
>>
,
substs
:
TypedArena
<
Substs
<
'tcx
>>
,
bare_fn
:
TypedArena
<
BareFnTy
<
'tcx
>>
,
region
:
TypedArena
<
Region
>
,
}
impl
<
'tcx
>
CtxtArenas
<
'tcx
>
{
...
...
@@ -617,6 +618,7 @@ pub fn new() -> CtxtArenas<'tcx> {
type_
:
TypedArena
::
new
(),
substs
:
TypedArena
::
new
(),
bare_fn
:
TypedArena
::
new
(),
region
:
TypedArena
::
new
(),
}
}
}
...
...
@@ -636,6 +638,7 @@ pub struct ctxt<'tcx> {
// FIXME as above, use a hashset if equivalent elements can be queried.
substs_interner
:
RefCell
<
FnvHashMap
<&
'tcx
Substs
<
'tcx
>
,
&
'tcx
Substs
<
'tcx
>>>
,
bare_fn_interner
:
RefCell
<
FnvHashMap
<&
'tcx
BareFnTy
<
'tcx
>
,
&
'tcx
BareFnTy
<
'tcx
>>>
,
region_interner
:
RefCell
<
FnvHashMap
<&
'tcx
Region
,
&
'tcx
Region
>>
,
pub
sess
:
Session
,
pub
def_map
:
DefMap
,
...
...
@@ -1340,7 +1343,7 @@ pub enum sty<'tcx> {
ty_str
,
ty_vec
(
Ty
<
'tcx
>
,
Option
<
uint
>
),
// Second field is length.
ty_ptr
(
mt
<
'tcx
>
),
ty_rptr
(
Region
,
mt
<
'tcx
>
),
ty_rptr
(
&
'tcx
Region
,
mt
<
'tcx
>
),
// If the def-id is Some(_), then this is the type of a specific
// fn item. Otherwise, if None(_), it a fn pointer type.
...
...
@@ -1350,7 +1353,7 @@ pub enum sty<'tcx> {
ty_trait
(
Box
<
TyTrait
<
'tcx
>>
),
ty_struct
(
DefId
,
&
'tcx
Substs
<
'tcx
>
),
ty_unboxed_closure
(
DefId
,
Region
,
&
'tcx
Substs
<
'tcx
>
),
ty_unboxed_closure
(
DefId
,
&
'tcx
Region
,
&
'tcx
Substs
<
'tcx
>
),
ty_tup
(
Vec
<
Ty
<
'tcx
>>
),
...
...
@@ -2085,6 +2088,7 @@ pub fn mk_ctxt<'tcx>(s: Session,
interner
:
RefCell
::
new
(
FnvHashMap
::
new
()),
substs_interner
:
RefCell
::
new
(
FnvHashMap
::
new
()),
bare_fn_interner
:
RefCell
::
new
(
FnvHashMap
::
new
()),
region_interner
:
RefCell
::
new
(
FnvHashMap
::
new
()),
named_region_map
:
named_region_map
,
item_variance_map
:
RefCell
::
new
(
DefIdMap
::
new
()),
variance_computed
:
Cell
::
new
(
false
),
...
...
@@ -2164,6 +2168,16 @@ pub fn mk_bare_fn(&self, bare_fn: BareFnTy<'tcx>) -> &'tcx BareFnTy<'tcx> {
self
.bare_fn_interner
.borrow_mut
()
.insert
(
bare_fn
,
bare_fn
);
bare_fn
}
pub
fn
mk_region
(
&
self
,
region
:
Region
)
->
&
'tcx
Region
{
if
let
Some
(
region
)
=
self
.region_interner
.borrow
()
.get
(
&
region
)
{
return
*
region
;
}
let
region
=
self
.arenas.region
.alloc
(
region
);
self
.region_interner
.borrow_mut
()
.insert
(
region
,
region
);
region
}
}
// Interns a type/name combination, stores the resulting box in cx.interner,
...
...
@@ -2269,7 +2283,7 @@ fn add_sty(&mut self, st: &sty) {
}
}
&
ty_unboxed_closure
(
_
,
re
f
re
gion
,
substs
)
=>
{
&
ty_unboxed_closure
(
_
,
region
,
substs
)
=>
{
self
.add_region
(
*
region
);
self
.add_substs
(
substs
);
}
...
...
@@ -2299,7 +2313,7 @@ fn add_sty(&mut self, st: &sty) {
}
&
ty_rptr
(
r
,
ref
m
)
=>
{
self
.add_region
(
r
);
self
.add_region
(
*
r
);
self
.add_ty
(
m
.ty
);
}
...
...
@@ -2404,7 +2418,7 @@ pub fn mk_str<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
mk_t
(
cx
,
ty_str
)
}
pub
fn
mk_str_slice
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
Region
,
m
:
ast
::
Mutability
)
->
Ty
<
'tcx
>
{
pub
fn
mk_str_slice
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
&
'tcx
Region
,
m
:
ast
::
Mutability
)
->
Ty
<
'tcx
>
{
mk_rptr
(
cx
,
r
,
mt
{
ty
:
mk_t
(
cx
,
ty_str
),
...
...
@@ -2421,14 +2435,14 @@ pub fn mk_uniq<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { mk_t(cx, ty_un
pub
fn
mk_ptr
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
tm
:
mt
<
'tcx
>
)
->
Ty
<
'tcx
>
{
mk_t
(
cx
,
ty_ptr
(
tm
))
}
pub
fn
mk_rptr
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
Region
,
tm
:
mt
<
'tcx
>
)
->
Ty
<
'tcx
>
{
pub
fn
mk_rptr
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
&
'tcx
Region
,
tm
:
mt
<
'tcx
>
)
->
Ty
<
'tcx
>
{
mk_t
(
cx
,
ty_rptr
(
r
,
tm
))
}
pub
fn
mk_mut_rptr
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
Region
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
pub
fn
mk_mut_rptr
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
&
'tcx
Region
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
mk_rptr
(
cx
,
r
,
mt
{
ty
:
ty
,
mutbl
:
ast
::
MutMutable
})
}
pub
fn
mk_imm_rptr
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
Region
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
pub
fn
mk_imm_rptr
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
&
'tcx
Region
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
mk_rptr
(
cx
,
r
,
mt
{
ty
:
ty
,
mutbl
:
ast
::
MutImmutable
})
}
...
...
@@ -2448,7 +2462,7 @@ pub fn mk_vec<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, sz: Option<uint>) -> Ty<'tcx>
mk_t
(
cx
,
ty_vec
(
ty
,
sz
))
}
pub
fn
mk_slice
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
Region
,
tm
:
mt
<
'tcx
>
)
->
Ty
<
'tcx
>
{
pub
fn
mk_slice
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
r
:
&
'tcx
Region
,
tm
:
mt
<
'tcx
>
)
->
Ty
<
'tcx
>
{
mk_rptr
(
cx
,
r
,
mt
{
ty
:
mk_vec
(
cx
,
tm
.ty
,
None
),
...
...
@@ -2512,7 +2526,7 @@ pub fn mk_struct<'tcx>(cx: &ctxt<'tcx>, struct_id: ast::DefId,
}
pub
fn
mk_unboxed_closure
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
closure_id
:
ast
::
DefId
,
region
:
Region
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
region
:
&
'tcx
Region
,
substs
:
&
'tcx
Substs
<
'tcx
>
)
->
Ty
<
'tcx
>
{
mk_t
(
cx
,
ty_unboxed_closure
(
closure_id
,
region
,
substs
))
}
...
...
@@ -3087,9 +3101,10 @@ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
ty_rptr
(
r
,
ref
mt
)
=>
{
TC
::
ReachesFfiUnsafe
|
match
mt
.ty.sty
{
ty_str
=>
borrowed_contents
(
r
,
ast
::
MutImmutable
),
ty_vec
(
..
)
=>
tc_ty
(
cx
,
mt
.ty
,
cache
)
.reference
(
borrowed_contents
(
r
,
mt
.mutbl
)),
_
=>
tc_ty
(
cx
,
mt
.ty
,
cache
)
.reference
(
borrowed_contents
(
r
,
mt
.mutbl
)),
ty_str
=>
borrowed_contents
(
*
r
,
ast
::
MutImmutable
),
ty_vec
(
..
)
=>
tc_ty
(
cx
,
mt
.ty
,
cache
)
.reference
(
borrowed_contents
(
*
r
,
mt
.mutbl
)),
_
=>
tc_ty
(
cx
,
mt
.ty
,
cache
)
.reference
(
borrowed_contents
(
*
r
,
mt
.mutbl
)),
}
}
...
...
@@ -3124,7 +3139,7 @@ fn tc_ty<'tcx>(cx: &ctxt<'tcx>,
let
upvars
=
unboxed_closure_upvars
(
cx
,
did
,
substs
);
TypeContents
::
union
(
upvars
.as_slice
(),
|
f
|
tc_ty
(
cx
,
f
.ty
,
cache
))
|
borrowed_contents
(
r
,
MutMutable
)
|
borrowed_contents
(
*
r
,
MutMutable
)
}
ty_tup
(
ref
tys
)
=>
{
...
...
@@ -3796,7 +3811,7 @@ pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
pub
fn
close_type
<
'tcx
>
(
cx
:
&
ctxt
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
ty
.sty
{
ty_open
(
ty
)
=>
mk_rptr
(
cx
,
ReStatic
,
mt
{
ty
:
ty
,
mutbl
:
ast
::
MutImmutable
}),
ty_open
(
ty
)
=>
mk_rptr
(
cx
,
cx
.mk_region
(
ReStatic
)
,
mt
{
ty
:
ty
,
mutbl
:
ast
::
MutImmutable
}),
_
=>
cx
.sess
.bug
(
format!
(
"Trying to close a non-open type {}"
,
ty_to_string
(
cx
,
ty
))[])
}
...
...
@@ -4000,7 +4015,7 @@ pub fn ty_region(tcx: &ctxt,
span
:
Span
,
ty
:
Ty
)
->
Region
{
match
ty
.sty
{
ty_rptr
(
r
,
_
)
=>
r
,
ty_rptr
(
r
,
_
)
=>
*
r
,
ref
s
=>
{
tcx
.sess
.span_bug
(
span
,
...
...
@@ -4206,7 +4221,7 @@ pub fn adjust_ty_for_autoref<'tcx>(cx: &ctxt<'tcx>,
&
Some
(
box
ref
a
)
=>
adjust_ty_for_autoref
(
cx
,
span
,
ty
,
Some
(
a
)),
&
None
=>
ty
};
mk_rptr
(
cx
,
r
,
mt
{
mk_rptr
(
cx
,
cx
.mk_region
(
r
)
,
mt
{
ty
:
adjusted_ty
,
mutbl
:
m
})
...
...
@@ -5494,7 +5509,7 @@ pub fn unboxed_closure_upvars<'tcx>(tcx: &ctxt<'tcx>, closure_id: ast::DefId, su
var_id
:
freevar_def_id
.node
,
closure_expr_id
:
closure_id
.node
}]
.clone
();
freevar_ty
=
mk_rptr
(
tcx
,
borrow
.region
,
ty
::
mt
{
freevar_ty
=
mk_rptr
(
tcx
,
tcx
.mk_region
(
borrow
.region
)
,
ty
::
mt
{
ty
:
freevar_ty
,
mutbl
:
borrow
.kind
.to_mutbl_lossy
()
});
...
...
@@ -6348,7 +6363,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
walk_ty
(
ty
,
|
ty
|
{
match
ty
.sty
{
ty_rptr
(
region
,
_
)
=>
{
accumulator
.push
(
region
)
accumulator
.push
(
*
region
)
}
ty_trait
(
ref
t
)
=>
{
accumulator
.push_all
(
t
.principal
.substs
()
.regions
()
.as_slice
());
...
...
@@ -6363,7 +6378,7 @@ pub fn accumulate_lifetimes_in_type(accumulator: &mut Vec<ty::Region>,
UniqTraitStore
=>
{}
}
}
ty_unboxed_closure
(
_
,
re
f
re
gion
,
substs
)
=>
{
ty_unboxed_closure
(
_
,
region
,
substs
)
=>
{
accumulator
.push
(
*
region
);
accum_substs
(
accumulator
,
substs
);
}
...
...
src/librustc/util/ppaux.rs
浏览文件 @
85970d49
...
...
@@ -401,7 +401,7 @@ fn infer_ty_to_string(cx: &ctxt, ty: ty::InferTy) -> String {
},
ty_to_string
(
cx
,
tm
.ty
))
}
ty_rptr
(
r
,
ref
tm
)
=>
{
let
mut
buf
=
region_ptr_to_string
(
cx
,
r
);
let
mut
buf
=
region_ptr_to_string
(
cx
,
*
r
);
buf
.push_str
(
mt_to_string
(
cx
,
tm
)[]);
buf
}
...
...
src/librustc_trans/trans/_match.rs
浏览文件 @
85970d49
...
...
@@ -635,7 +635,7 @@ fn bind_subslice_pat(bcx: Block,
let
slice_len_offset
=
C_uint
(
bcx
.ccx
(),
offset_left
+
offset_right
);
let
slice_len
=
Sub
(
bcx
,
len
,
slice_len_offset
);
let
slice_ty
=
ty
::
mk_slice
(
bcx
.tcx
(),
ty
::
ReStatic
,
bcx
.tcx
()
.mk_region
(
ty
::
ReStatic
)
,
ty
::
mt
{
ty
:
vt
.unit_ty
,
mutbl
:
ast
::
MutImmutable
});
let
scratch
=
rvalue_scratch_datum
(
bcx
,
slice_ty
,
""
);
Store
(
bcx
,
slice_begin
,
...
...
@@ -808,7 +808,9 @@ fn compare_str<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
ty
::
ty_uint
(
ast
::
TyU8
)
=>
{
// NOTE: cast &[u8] to &str and abuse the str_eq lang item,
// which calls memcmp().
let
t
=
ty
::
mk_str_slice
(
cx
.tcx
(),
ty
::
ReStatic
,
ast
::
MutImmutable
);
let
t
=
ty
::
mk_str_slice
(
cx
.tcx
(),
cx
.tcx
()
.mk_region
(
ty
::
ReStatic
),
ast
::
MutImmutable
);
let
lhs
=
BitCast
(
cx
,
lhs
,
type_of
::
type_of
(
cx
.ccx
(),
t
)
.ptr_to
());
let
rhs
=
BitCast
(
cx
,
rhs
,
type_of
::
type_of
(
cx
.ccx
(),
t
)
.ptr_to
());
compare_str
(
cx
,
lhs
,
rhs
,
rhs_t
)
...
...
src/librustc_trans/trans/base.rs
浏览文件 @
85970d49
...
...
@@ -264,10 +264,10 @@ pub fn self_type_for_unboxed_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let
unboxed_closure
=
&
(
*
unboxed_closures
)[
closure_id
];
match
unboxed_closure
.kind
{
ty
::
FnUnboxedClosureKind
=>
{
ty
::
mk_imm_rptr
(
ccx
.tcx
(),
ty
::
ReStatic
,
fn_ty
)
ty
::
mk_imm_rptr
(
ccx
.tcx
(),
ccx
.tcx
()
.mk_region
(
ty
::
ReStatic
)
,
fn_ty
)
}
ty
::
FnMutUnboxedClosureKind
=>
{
ty
::
mk_mut_rptr
(
ccx
.tcx
(),
ty
::
ReStatic
,
fn_ty
)
ty
::
mk_mut_rptr
(
ccx
.tcx
(),
ccx
.tcx
()
.mk_region
(
ty
::
ReStatic
)
,
fn_ty
)
}
ty
::
FnOnceUnboxedClosureKind
=>
fn_ty
}
...
...
@@ -2599,14 +2599,14 @@ pub fn get_fn_llvm_attributes<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_ty: Ty<
attrs
.arg
(
idx
,
llvm
::
ReadOnlyAttribute
);
}
if
let
ReLateBound
(
_
,
BrAnon
(
_
))
=
b
{
if
let
ReLateBound
(
_
,
BrAnon
(
_
))
=
*
b
{
attrs
.arg
(
idx
,
llvm
::
NoCaptureAttribute
);
}
}
// When a reference in an argument has no named lifetime, it's impossible for that
// reference to escape this function (returned or stored beyond the call by a closure).
ty
::
ty_rptr
(
ReLateBound
(
_
,
BrAnon
(
_
)),
mt
)
=>
{
ty
::
ty_rptr
(
&
ReLateBound
(
_
,
BrAnon
(
_
)),
mt
)
=>
{
let
llsz
=
llsize_of_real
(
ccx
,
type_of
::
type_of
(
ccx
,
mt
.ty
));
attrs
.arg
(
idx
,
llvm
::
NoCaptureAttribute
)
.arg
(
idx
,
llvm
::
DereferenceableAttribute
(
llsz
));
...
...
src/librustc_trans/trans/expr.rs
浏览文件 @
85970d49
...
...
@@ -2130,7 +2130,7 @@ fn auto_ref<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// Compute final type. Note that we are loose with the region and
// mutability, since those things don't matter in trans.
let
referent_ty
=
lv_datum
.ty
;
let
ptr_ty
=
ty
::
mk_imm_rptr
(
bcx
.tcx
(),
ty
::
ReStatic
,
referent_ty
);
let
ptr_ty
=
ty
::
mk_imm_rptr
(
bcx
.tcx
(),
bcx
.tcx
()
.mk_region
(
ty
::
ReStatic
)
,
referent_ty
);
// Get the pointer.
let
llref
=
lv_datum
.to_llref
();
...
...
src/librustc_typeck/astconv.rs
浏览文件 @
85970d49
...
...
@@ -940,7 +940,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
let
r
=
opt_ast_region_to_region
(
this
,
rscope
,
ast_ty
.span
,
region
);
debug!
(
"ty_rptr r={}"
,
r
.repr
(
this
.tcx
()));
let
t
=
ast_ty_to_ty
(
this
,
rscope
,
&*
mt
.ty
);
ty
::
mk_rptr
(
tcx
,
r
,
ty
::
mt
{
ty
:
t
,
mutbl
:
mt
.mutbl
})
ty
::
mk_rptr
(
tcx
,
tcx
.mk_region
(
r
)
,
ty
::
mt
{
ty
:
t
,
mutbl
:
mt
.mutbl
})
}
ast
::
TyTup
(
ref
fields
)
=>
{
let
flds
=
fields
.iter
()
...
...
@@ -1218,7 +1218,7 @@ fn ty_of_method_or_bare_fn<'a, 'tcx, AC: AstConv<'tcx>>(
}
ty
::
ByReferenceExplicitSelfCategory
(
region
,
mutability
)
=>
{
(
Some
(
ty
::
mk_rptr
(
this
.tcx
(),
region
,
this
.tcx
()
.mk_region
(
region
)
,
ty
::
mt
{
ty
:
self_info
.untransformed_self_ty
,
mutbl
:
mutability
...
...
@@ -1351,7 +1351,7 @@ fn determine_explicit_self_category<'a, 'tcx, AC: AstConv<'tcx>,
ty
::
ByValueExplicitSelfCategory
}
else
{
match
explicit_type
.sty
{
ty
::
ty_rptr
(
r
,
mt
)
=>
ty
::
ByReferenceExplicitSelfCategory
(
r
,
mt
.mutbl
),
ty
::
ty_rptr
(
r
,
mt
)
=>
ty
::
ByReferenceExplicitSelfCategory
(
*
r
,
mt
.mutbl
),
ty
::
ty_uniq
(
_
)
=>
ty
::
ByBoxExplicitSelfCategory
,
_
=>
ty
::
ByValueExplicitSelfCategory
,
}
...
...
src/librustc_typeck/check/_match.rs
浏览文件 @
85970d49
...
...
@@ -93,7 +93,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
// and T is the expected type
let
region_var
=
fcx
.infcx
()
.next_region_var
(
infer
::
PatternRegion
(
pat
.span
));
let
mt
=
ty
::
mt
{
ty
:
expected
,
mutbl
:
mutbl
};
let
region_ty
=
ty
::
mk_rptr
(
tcx
,
region_var
,
mt
);
let
region_ty
=
ty
::
mk_rptr
(
tcx
,
tcx
.mk_region
(
region_var
)
,
mt
);
demand
::
eqtype
(
fcx
,
pat
.span
,
region_ty
,
typ
);
}
// otherwise the type of x is the expected type T
...
...
@@ -154,7 +154,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
let
mt
=
ty
::
mt
{
ty
:
inner_ty
,
mutbl
:
mutbl
};
let
region
=
fcx
.infcx
()
.next_region_var
(
infer
::
PatternRegion
(
pat
.span
));
let
rptr_ty
=
ty
::
mk_rptr
(
tcx
,
region
,
mt
);
let
rptr_ty
=
ty
::
mk_rptr
(
tcx
,
tcx
.mk_region
(
region
)
,
mt
);
if
check_dereferencable
(
pcx
,
pat
.span
,
expected
,
&**
inner
)
{
demand
::
suptype
(
fcx
,
pat
.span
,
expected
,
rptr_ty
);
...
...
@@ -178,7 +178,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
})),
_
=>
{
let
region
=
fcx
.infcx
()
.next_region_var
(
infer
::
PatternRegion
(
pat
.span
));
ty
::
mk_slice
(
tcx
,
region
,
ty
::
mt
{
ty
::
mk_slice
(
tcx
,
tcx
.mk_region
(
region
)
,
ty
::
mt
{
ty
:
inner_ty
,
mutbl
:
ty
::
deref
(
expected_ty
,
true
)
.map_or
(
ast
::
MutImmutable
,
|
mt
|
mt
.mutbl
)
...
...
@@ -197,7 +197,7 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
let
mutbl
=
ty
::
deref
(
expected_ty
,
true
)
.map_or
(
ast
::
MutImmutable
,
|
mt
|
mt
.mutbl
);
let
slice_ty
=
ty
::
mk_slice
(
tcx
,
region
,
ty
::
mt
{
let
slice_ty
=
ty
::
mk_slice
(
tcx
,
tcx
.mk_region
(
region
)
,
ty
::
mt
{
ty
:
inner_ty
,
mutbl
:
mutbl
});
...
...
src/librustc_typeck/check/closure.rs
浏览文件 @
85970d49
...
...
@@ -126,7 +126,7 @@ fn check_unboxed_closure<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
let
closure_type
=
ty
::
mk_unboxed_closure
(
fcx
.ccx.tcx
,
expr_def_id
,
region
,
fcx
.ccx.tcx
.mk_region
(
region
)
,
fcx
.ccx.tcx
.mk_substs
(
fcx
.inh.param_env.free_substs
.clone
()));
...
...
src/librustc_typeck/check/method/mod.rs
浏览文件 @
85970d49
...
...
@@ -259,7 +259,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &'a FnCtxt<'a, 'tcx>,
span
,
ty
::
AdjustDerefRef
(
ty
::
AutoDerefRef
{
autoderefs
:
autoderefs
,
autoref
:
Some
(
ty
::
AutoPtr
(
region
,
mutbl
,
autoref
))
autoref
:
Some
(
ty
::
AutoPtr
(
*
region
,
mutbl
,
autoref
))
}));
}
...
...
src/librustc_typeck/check/method/probe.rs
浏览文件 @
85970d49
...
...
@@ -657,7 +657,7 @@ fn pick_autorefd_method(&mut self,
let
tcx
=
self
.tcx
();
self
.search_mutabilities
(
|
m
|
AutoRef
(
m
,
box
step
.adjustment
.clone
()),
|
m
,
r
|
ty
::
mk_rptr
(
tcx
,
r
,
ty
::
mt
{
ty
:
step
.self_ty
,
mutbl
:
m
}))
|
m
,
r
|
ty
::
mk_rptr
(
tcx
,
tcx
.mk_region
(
r
)
,
ty
::
mt
{
ty
:
step
.self_ty
,
mutbl
:
m
}))
}
fn
search_mutabilities
<
F
,
G
>
(
&
mut
self
,
...
...
src/librustc_typeck/check/mod.rs
浏览文件 @
85970d49
...
...
@@ -2736,9 +2736,10 @@ fn check_lit<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let
tcx
=
fcx
.ccx.tcx
;
match
lit
.node
{
ast
::
LitStr
(
..
)
=>
ty
::
mk_str_slice
(
tcx
,
t
y
::
ReStatic
,
ast
::
MutImmutable
),
ast
::
LitStr
(
..
)
=>
ty
::
mk_str_slice
(
tcx
,
t
cx
.mk_region
(
ty
::
ReStatic
)
,
ast
::
MutImmutable
),
ast
::
LitBinary
(
..
)
=>
{
ty
::
mk_slice
(
tcx
,
ty
::
ReStatic
,
ty
::
mt
{
ty
:
ty
::
mk_u8
(),
mutbl
:
ast
::
MutImmutable
})
ty
::
mk_slice
(
tcx
,
tcx
.mk_region
(
ty
::
ReStatic
),
ty
::
mt
{
ty
:
ty
::
mk_u8
(),
mutbl
:
ast
::
MutImmutable
})
}
ast
::
LitByte
(
_
)
=>
ty
::
mk_u8
(),
ast
::
LitChar
(
_
)
=>
ty
::
mk_char
(),
...
...
@@ -3098,8 +3099,8 @@ fn lookup_op_method<'a, 'tcx, F>(fcx: &'a FnCtxt<'a, 'tcx>,
let
(
adj_ty
,
adjustment
)
=
match
lhs_ty
.sty
{
ty
::
ty_rptr
(
r_in
,
mt
)
=>
{
let
r_adj
=
fcx
.infcx
()
.next_region_var
(
infer
::
Autoref
(
lhs
.span
));
fcx
.mk_subr
(
infer
::
Reborrow
(
lhs
.span
),
r_adj
,
r_in
);
let
adjusted_ty
=
ty
::
mk_rptr
(
fcx
.tcx
(),
r_adj
,
mt
);
fcx
.mk_subr
(
infer
::
Reborrow
(
lhs
.span
),
r_adj
,
*
r_in
);
let
adjusted_ty
=
ty
::
mk_rptr
(
fcx
.tcx
(),
fcx
.tcx
()
.mk_region
(
r_adj
)
,
mt
);
let
autoptr
=
ty
::
AutoPtr
(
r_adj
,
mt
.mutbl
,
None
);
let
adjustment
=
ty
::
AutoDerefRef
{
autoderefs
:
1
,
autoref
:
Some
(
autoptr
)
};
(
adjusted_ty
,
adjustment
)
...
...
@@ -3839,11 +3840,11 @@ fn check_struct_fields_on_error(fcx: &FnCtxt,
// `'static`!
let
region
=
fcx
.infcx
()
.next_region_var
(
infer
::
AddrOfSlice
(
expr
.span
));
ty
::
mk_rptr
(
tcx
,
region
,
tm
)
ty
::
mk_rptr
(
tcx
,
tcx
.mk_region
(
region
)
,
tm
)
}
_
=>
{
let
region
=
fcx
.infcx
()
.next_region_var
(
infer
::
AddrOfRegion
(
expr
.span
));
ty
::
mk_rptr
(
tcx
,
region
,
tm
)
ty
::
mk_rptr
(
tcx
,
tcx
.mk_region
(
region
)
,
tm
)
}
}
};
...
...
@@ -5568,7 +5569,9 @@ fn param<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, n: u32) -> Ty<'tcx> {
"move_val_init"
=>
{
(
1u
,
vec!
(
ty
::
mk_mut_rptr
(
tcx
,
ty
::
ReLateBound
(
ty
::
DebruijnIndex
::
new
(
1
),
ty
::
BrAnon
(
0
)),
ty
::
mk_mut_rptr
(
tcx
,
tcx
.mk_region
(
ty
::
ReLateBound
(
ty
::
DebruijnIndex
::
new
(
1
),
ty
::
BrAnon
(
0
))),
param
(
ccx
,
0
)),
param
(
ccx
,
0
)
),
...
...
src/librustc_typeck/check/regionck.rs
浏览文件 @
85970d49
...
...
@@ -645,7 +645,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
};
if
let
ty
::
ty_rptr
(
r_ptr
,
_
)
=
base_ty
.sty
{
mk_subregion_due_to_dereference
(
rcx
,
expr
.span
,
ty
::
ReScope
(
CodeExtent
::
from_node_id
(
expr
.id
)),
r_ptr
);
rcx
,
expr
.span
,
ty
::
ReScope
(
CodeExtent
::
from_node_id
(
expr
.id
)),
*
r_ptr
);
}
visit
::
walk_expr
(
rcx
,
expr
);
...
...
@@ -763,7 +763,7 @@ fn walk_cast<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
/*From:*/
(
&
ty
::
ty_rptr
(
from_r
,
ref
from_mt
),
/*To: */
&
ty
::
ty_rptr
(
to_r
,
ref
to_mt
))
=>
{
// Target cannot outlive source, naturally.
rcx
.fcx
.mk_subr
(
infer
::
Reborrow
(
cast_expr
.span
),
to_r
,
from_r
);
rcx
.fcx
.mk_subr
(
infer
::
Reborrow
(
cast_expr
.span
),
*
to_r
,
*
from_r
);
walk_cast
(
rcx
,
cast_expr
,
from_mt
.ty
,
to_mt
.ty
);
}
...
...
@@ -822,7 +822,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
// Variables being referenced must be constrained and registered
// in the upvar borrow map
constrain_free_variables_in_by_ref_closure
(
rcx
,
region
,
expr
,
freevars
);
rcx
,
*
region
,
expr
,
freevars
);
}
})
}
...
...
@@ -858,7 +858,7 @@ fn check_expr_fn_block(rcx: &mut Rcx,
}
ty
::
ty_unboxed_closure
(
_
,
region
,
_
)
=>
{
ty
::
with_freevars
(
tcx
,
expr
.id
,
|
freevars
|
{
let
bounds
=
ty
::
region_existential_bound
(
region
);
let
bounds
=
ty
::
region_existential_bound
(
*
region
);
ensure_free_variable_types_outlive_closure_bound
(
rcx
,
bounds
,
expr
,
freevars
);
})
}
...
...
@@ -897,7 +897,7 @@ fn ensure_free_variable_types_outlive_closure_bound(
let
var_ty
=
match
rcx
.fcx.inh.upvar_borrow_map
.borrow
()
.get
(
&
upvar_id
)
{
Some
(
upvar_borrow
)
=>
{
ty
::
mk_rptr
(
rcx
.tcx
(),
upvar_borrow
.region
,
rcx
.tcx
()
.mk_region
(
upvar_borrow
.region
)
,
ty
::
mt
{
mutbl
:
upvar_borrow
.kind
.to_mutbl_lossy
(),
ty
:
raw_var_ty
})
}
...
...
@@ -1137,7 +1137,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
{
let
mc
=
mc
::
MemCategorizationContext
::
new
(
rcx
.fcx
);
let
self_cmt
=
mc
.cat_expr_autoderefd
(
deref_expr
,
i
);
link_region
(
rcx
,
deref_expr
.span
,
r
,
link_region
(
rcx
,
deref_expr
.span
,
*
r
,
ty
::
BorrowKind
::
from_mutbl
(
m
),
self_cmt
);
}
...
...
@@ -1158,7 +1158,7 @@ fn constrain_autoderefs<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
if
let
ty
::
ty_rptr
(
r_ptr
,
_
)
=
derefd_ty
.sty
{
mk_subregion_due_to_dereference
(
rcx
,
deref_expr
.span
,
r_deref_expr
,
r_ptr
);
r_deref_expr
,
*
r_ptr
);
}
match
ty
::
deref
(
derefd_ty
,
true
)
{
...
...
@@ -1193,7 +1193,7 @@ fn constrain_index<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
match
mt
.ty.sty
{
ty
::
ty_vec
(
_
,
None
)
|
ty
::
ty_str
=>
{
rcx
.fcx
.mk_subr
(
infer
::
IndexSlice
(
index_expr
.span
),
r_index_expr
,
r_ptr
);
r_index_expr
,
*
r_ptr
);
}
_
=>
{}
}
...
...
src/librustc_typeck/check/regionmanip.rs
浏览文件 @
85970d49
...
...
@@ -93,7 +93,7 @@ fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
// captured by reference it must also outlive the
// region bound on the closure, but this is explicitly
// handled by logic in regionck.
self
.push_region_constraint_from_top
(
region
);
self
.push_region_constraint_from_top
(
*
region
);
}
ty
::
ty_trait
(
ref
t
)
=>
{
...
...
@@ -114,7 +114,7 @@ fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
}
ty
::
ty_rptr
(
r_b
,
mt
)
=>
{
self
.accumulate_from_rptr
(
ty
,
r_b
,
mt
.ty
);
self
.accumulate_from_rptr
(
ty
,
*
r_b
,
mt
.ty
);
}
ty
::
ty_param
(
p
)
=>
{
...
...
src/librustc_typeck/check/vtable.rs
浏览文件 @
85970d49
...
...
@@ -63,8 +63,8 @@ pub fn check_object_cast<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
// Ensure that if &'a T is cast to &'b Trait, then 'b <= 'a
infer
::
mk_subr
(
fcx
.infcx
(),
infer
::
RelateObjectBound
(
source_expr
.span
),
target_region
,
referent_region
);
*
target_region
,
*
referent_region
);
check_object_safety
(
fcx
.tcx
(),
object_trait
,
source_expr
.span
);
}
...
...
src/librustc_typeck/variance.rs
浏览文件 @
85970d49
...
...
@@ -732,7 +732,7 @@ fn add_constraints_from_ty(&mut self,
ty
::
ty_rptr
(
region
,
ref
mt
)
=>
{
let
contra
=
self
.contravariant
(
variance
);
self
.add_constraints_from_region
(
region
,
contra
);
self
.add_constraints_from_region
(
*
region
,
contra
);
self
.add_constraints_from_mt
(
mt
,
variance
);
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录