Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
cfcbec3c
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,发现更多精彩内容 >>
提交
cfcbec3c
编写于
3月 14, 2012
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement an initial version of placement new.
上级
ba39e277
变更
22
隐藏空白更改
内联
并排
Showing
22 changed file
with
266 addition
and
87 deletion
+266
-87
src/cargo/cargo.rs
src/cargo/cargo.rs
+4
-4
src/fuzzer/fuzzer.rs
src/fuzzer/fuzzer.rs
+9
-9
src/libcore/path.rs
src/libcore/path.rs
+9
-9
src/libcore/vec.rs
src/libcore/vec.rs
+7
-7
src/rustc/middle/resolve.rs
src/rustc/middle/resolve.rs
+3
-0
src/rustc/middle/trans/base.rs
src/rustc/middle/trans/base.rs
+78
-26
src/rustc/middle/trans/native.rs
src/rustc/middle/trans/native.rs
+12
-11
src/rustc/middle/trans/type_use.rs
src/rustc/middle/trans/type_use.rs
+3
-0
src/rustc/middle/tstate/ann.rs
src/rustc/middle/tstate/ann.rs
+4
-4
src/rustc/middle/tstate/auxiliary.rs
src/rustc/middle/tstate/auxiliary.rs
+3
-3
src/rustc/middle/tstate/pre_post_conditions.rs
src/rustc/middle/tstate/pre_post_conditions.rs
+3
-0
src/rustc/middle/tstate/states.rs
src/rustc/middle/tstate/states.rs
+3
-0
src/rustc/middle/tstate/tritv.rs
src/rustc/middle/tstate/tritv.rs
+11
-11
src/rustc/middle/typeck.rs
src/rustc/middle/typeck.rs
+51
-0
src/rustc/syntax/ast.rs
src/rustc/syntax/ast.rs
+4
-0
src/rustc/syntax/fold.rs
src/rustc/syntax/fold.rs
+5
-0
src/rustc/syntax/parse/parser.rs
src/rustc/syntax/parse/parser.rs
+8
-1
src/rustc/syntax/print/pprust.rs
src/rustc/syntax/print/pprust.rs
+7
-0
src/rustc/syntax/visit.rs
src/rustc/syntax/visit.rs
+4
-0
src/test/compile-fail/placement-new-bad-method-type.rs
src/test/compile-fail/placement-new-bad-method-type.rs
+15
-0
src/test/run-pass/chan-leak.rs
src/test/run-pass/chan-leak.rs
+2
-2
src/test/run-pass/placement-new-leaky.rs
src/test/run-pass/placement-new-leaky.rs
+21
-0
未找到文件。
src/cargo/cargo.rs
浏览文件 @
cfcbec3c
...
...
@@ -434,8 +434,8 @@ fn for_each_package(c: cargo, b: fn(source, package)) {
// Runs all programs in directory <buildpath>
fn
run_programs
(
buildpath
:
str
)
{
let
new
=
os
::
list_dir
(
buildpath
);
for
ct
:
str
in
new
{
let
new
v
=
os
::
list_dir
(
buildpath
);
for
ct
:
str
in
new
v
{
run
::
run_program
(
ct
,
[]);
}
}
...
...
@@ -471,9 +471,9 @@ fn install_one_crate(c: cargo, path: str, cf: str) {
none
{
ret
;
}
some
(
bp
)
{
bp
}
};
let
new
=
os
::
list_dir
(
buildpath
);
let
new
v
=
os
::
list_dir
(
buildpath
);
let
exec_suffix
=
os
::
exe_suffix
();
for
ct
:
str
in
new
{
for
ct
:
str
in
new
v
{
if
(
exec_suffix
!=
""
&&
str
::
ends_with
(
ct
,
exec_suffix
))
||
(
exec_suffix
==
""
&&
!
str
::
starts_with
(
path
::
basename
(
ct
),
"lib"
))
{
...
...
src/fuzzer/fuzzer.rs
浏览文件 @
cfcbec3c
...
...
@@ -488,23 +488,23 @@ fn file_might_not_converge(filename: str) -> bool {
fn
check_roundtrip_convergence
(
code
:
@
str
,
maxIters
:
uint
)
{
let
i
=
0u
;
let
new
=
code
;
let
old
=
code
;
let
new
v
=
code
;
let
old
v
=
code
;
while
i
<
maxIters
{
old
=
new
;
if
content_might_not_converge
(
*
old
)
{
ret
;
}
new
=
@
parse_and_print
(
old
);
if
old
==
new
{
break
;
}
old
v
=
newv
;
if
content_might_not_converge
(
*
old
v
)
{
ret
;
}
new
v
=
@
parse_and_print
(
oldv
);
if
old
v
==
newv
{
break
;
}
i
+=
1u
;
}
if
old
==
new
{
if
old
v
==
newv
{
#
error
(
"Converged after %u iterations"
,
i
);
}
else
{
#
error
(
"Did not converge after %u iterations!"
,
i
);
write_file
(
"round-trip-a.rs"
,
*
old
);
write_file
(
"round-trip-b.rs"
,
*
new
);
write_file
(
"round-trip-a.rs"
,
*
old
v
);
write_file
(
"round-trip-b.rs"
,
*
new
v
);
run
::
run_program
(
"diff"
,
[
"-w"
,
"-u"
,
"round-trip-a.rs"
,
"round-trip-b.rs"
]);
...
...
src/libcore/path.rs
浏览文件 @
cfcbec3c
...
...
@@ -266,30 +266,30 @@ fn rollup_doubledots(s: [path]) -> [path] {
#[cfg(target_os
=
"linux"
)]
#[cfg(target_os
=
"macos"
)]
#[cfg(target_os
=
"freebsd"
)]
fn
reabsolute
(
orig
:
path
,
n
ew
:
path
)
->
path
{
fn
reabsolute
(
orig
:
path
,
n
:
path
)
->
path
{
if
path_is_absolute
(
orig
)
{
path_sep
()
+
n
ew
path_sep
()
+
n
}
else
{
n
ew
n
}
}
#[cfg(target_os
=
"win32"
)]
fn
reabsolute
(
orig
:
path
,
new
:
path
)
->
path
{
fn
reabsolute
(
orig
:
path
,
new
p
:
path
)
->
path
{
if
path_is_absolute
(
orig
)
&&
orig
[
0
]
==
consts
::
path_sep
as
u8
{
str
::
from_char
(
consts
::
path_sep
)
+
new
str
::
from_char
(
consts
::
path_sep
)
+
new
p
}
else
{
new
new
p
}
}
fn
reterminate
(
orig
:
path
,
new
:
path
)
->
path
{
fn
reterminate
(
orig
:
path
,
new
p
:
path
)
->
path
{
let
last
=
orig
[
str
::
len
(
orig
)
-
1u
];
if
last
==
consts
::
path_sep
as
u8
||
last
==
consts
::
path_sep
as
u8
{
ret
new
+
path_sep
();
ret
new
p
+
path_sep
();
}
else
{
ret
new
;
ret
new
p
;
}
}
}
...
...
src/libcore/vec.rs
浏览文件 @
cfcbec3c
...
...
@@ -468,22 +468,22 @@ fn filter<T: copy>(v: [T], f: fn(T) -> bool) -> [T] {
Flattens a vector of vectors of T into a single vector of T.
"
]
fn
concat
<
T
:
copy
>
(
v
:
[
const
[
const
T
]])
->
[
T
]
{
let
mut
new
:
[
T
]
=
[];
for
inner
:
[
T
]
in
v
{
new
+=
inner
;
}
ret
new
;
let
mut
r
:
[
T
]
=
[];
for
inner
:
[
T
]
in
v
{
r
+=
inner
;
}
ret
r
;
}
#[doc
=
"
Concatenate a vector of vectors, placing a given separator between each
"
]
fn
connect
<
T
:
copy
>
(
v
:
[
const
[
const
T
]],
sep
:
T
)
->
[
T
]
{
let
mut
new
:
[
T
]
=
[];
let
mut
r
:
[
T
]
=
[];
let
mut
first
=
true
;
for
inner
:
[
T
]
in
v
{
if
first
{
first
=
false
;
}
else
{
push
(
new
,
sep
);
}
new
+=
inner
;
if
first
{
first
=
false
;
}
else
{
push
(
r
,
sep
);
}
r
+=
inner
;
}
ret
new
;
ret
r
;
}
#[doc
=
"Reduce a vector from left to right"
]
...
...
src/rustc/middle/resolve.rs
浏览文件 @
cfcbec3c
...
...
@@ -2308,6 +2308,9 @@ fn resolve_impl_in_expr(e: @env, x: @ast::expr, sc: iscopes, v: vt<iscopes>) {
ast
::
expr_assign_op
(
_
,
_
,
_
)
|
ast
::
expr_index
(
_
,
_
)
{
e
.impl_map
.insert
(
x
.id
,
sc
);
}
ast
::
expr_new
(
p
,
_
,
_
)
{
e
.impl_map
.insert
(
p
.id
,
sc
);
}
_
{}
}
visit
::
visit_expr
(
x
,
sc
,
v
);
...
...
src/rustc/middle/trans/base.rs
浏览文件 @
cfcbec3c
...
...
@@ -1261,9 +1261,9 @@ fn trans_unary(bcx: block, op: ast::unop, e: @ast::expr,
some
(
origin
)
{
let
callee_id
=
ast_util
::
op_expr_callee_id
(
un_expr
);
let
fty
=
node_id_type
(
bcx
,
callee_id
);
ret
trans_call_inner
(
bcx
,
fty
,
{|
bcx
|
ret
trans_call_inner
(
bcx
,
fty
,
expr_ty
(
bcx
,
un_expr
),
{|
bcx
|
impl
::
trans_method_callee
(
bcx
,
callee_id
,
e
,
origin
)
},
[],
un_expr
.id
,
dest
);
},
arg_exprs
([])
,
dest
);
}
_
{}
}
...
...
@@ -1450,10 +1450,10 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
some
(
origin
)
{
let
callee_id
=
ast_util
::
op_expr_callee_id
(
ex
);
let
fty
=
node_id_type
(
bcx
,
callee_id
);
ret
trans_call_inner
(
bcx
,
fty
,
{|
bcx
|
ret
trans_call_inner
(
bcx
,
fty
,
expr_ty
(
bcx
,
ex
),
{|
bcx
|
// FIXME provide the already-computed address, not the expr
impl
::
trans_method_callee
(
bcx
,
callee_id
,
dst
,
origin
)
},
[
src
],
ex
.id
,
save_in
(
lhs_res
.val
));
},
arg_exprs
([
src
])
,
save_in
(
lhs_res
.val
));
}
_
{}
}
...
...
@@ -1561,9 +1561,9 @@ fn trans_binary(bcx: block, op: ast::binop, lhs: @ast::expr,
some
(
origin
)
{
let
callee_id
=
ast_util
::
op_expr_callee_id
(
ex
);
let
fty
=
node_id_type
(
bcx
,
callee_id
);
ret
trans_call_inner
(
bcx
,
fty
,
{|
bcx
|
ret
trans_call_inner
(
bcx
,
fty
,
expr_ty
(
bcx
,
ex
),
{|
bcx
|
impl
::
trans_method_callee
(
bcx
,
callee_id
,
lhs
,
origin
)
},
[
rhs
],
ex
.id
,
dest
);
},
arg_exprs
([
rhs
])
,
dest
);
}
_
{}
}
...
...
@@ -2498,6 +2498,10 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
ret
rslt
(
bcx
,
val
);
}
enum
call_args
{
arg_exprs
([
@
ast
::
expr
]),
arg_vals
([
ValueRef
])
}
// NB: must keep 4 fns in sync:
//
...
...
@@ -2505,12 +2509,12 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
// - create_llargs_for_fn_args.
// - new_fn_ctxt
// - trans_args
fn
trans_args
(
cx
:
block
,
llenv
:
ValueRef
,
es
:
[
@
ast
::
expr
]
,
fn_ty
:
ty
::
t
,
fn
trans_args
(
cx
:
block
,
llenv
:
ValueRef
,
args
:
call_args
,
fn_ty
:
ty
::
t
,
dest
:
dest
,
generic_intrinsic
:
bool
)
->
{
bcx
:
block
,
args
:
[
ValueRef
],
retslot
:
ValueRef
}
{
let
temp_cleanups
=
[];
let
args
=
ty
::
ty_fn_args
(
fn_ty
);
let
arg
_ty
s
=
ty
::
ty_fn_args
(
fn_ty
);
let
llargs
:
[
ValueRef
]
=
[];
let
ccx
=
cx
.ccx
();
...
...
@@ -2546,13 +2550,21 @@ fn trans_args(cx: block, llenv: ValueRef, es: [@ast::expr], fn_ty: ty::t,
// First we figure out the caller's view of the types of the arguments.
// This will be needed if this is a generic call, because the callee has
// to cast her view of the arguments to the caller's view.
let
arg_tys
=
type_of_explicit_args
(
ccx
,
args
);
let
i
=
0u
;
for
e
:
@
ast
::
expr
in
es
{
let
r
=
trans_arg_expr
(
bcx
,
args
[
i
],
arg_tys
[
i
],
e
,
temp_cleanups
);
bcx
=
r
.bcx
;
llargs
+=
[
r
.val
];
i
+=
1u
;
alt
args
{
arg_exprs
(
es
)
{
let
llarg_tys
=
type_of_explicit_args
(
ccx
,
arg_tys
);
let
i
=
0u
;
for
e
:
@
ast
::
expr
in
es
{
let
r
=
trans_arg_expr
(
bcx
,
arg_tys
[
i
],
llarg_tys
[
i
],
e
,
temp_cleanups
);
bcx
=
r
.bcx
;
llargs
+=
[
r
.val
];
i
+=
1u
;
}
}
arg_vals
(
vs
)
{
llargs
+=
vs
;
}
}
// now that all arguments have been successfully built, we can revoke any
...
...
@@ -2568,15 +2580,15 @@ fn trans_args(cx: block, llenv: ValueRef, es: [@ast::expr], fn_ty: ty::t,
}
fn
trans_call
(
in_cx
:
block
,
f
:
@
ast
::
expr
,
args
:
[
@
ast
::
expr
]
,
id
:
ast
::
node_id
,
dest
:
dest
)
args
:
call_args
,
id
:
ast
::
node_id
,
dest
:
dest
)
->
block
{
trans_call_inner
(
in_cx
,
expr_ty
(
in_cx
,
f
),
{|
cx
|
trans_callee
(
cx
,
f
)},
args
,
id
,
dest
)
trans_call_inner
(
in_cx
,
expr_ty
(
in_cx
,
f
),
node_id_type
(
in_cx
,
id
),
{|
cx
|
trans_callee
(
cx
,
f
)},
args
,
dest
)
}
fn
trans_call_inner
(
in_cx
:
block
,
fn_expr_ty
:
ty
::
t
,
fn
trans_call_inner
(
in_cx
:
block
,
fn_expr_ty
:
ty
::
t
,
ret_ty
:
ty
::
t
,
get_callee
:
fn
(
block
)
->
lval_maybe_callee
,
args
:
[
@
ast
::
expr
],
id
:
ast
::
node_id
,
dest
:
dest
)
args
:
call_args
,
dest
:
dest
)
->
block
{
with_scope
(
in_cx
,
"call"
)
{|
cx
|
let
f_res
=
get_callee
(
cx
);
...
...
@@ -2603,9 +2615,10 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t,
}
};
let
ret_ty
=
node_id_type
(
bcx
,
id
);
let
args_res
=
trans_args
(
bcx
,
llenv
,
args
,
fn_expr_ty
,
dest
,
option
::
is_some
(
f_res
.tds
));
let
args_res
=
{
trans_args
(
bcx
,
llenv
,
args
,
fn_expr_ty
,
dest
,
option
::
is_some
(
f_res
.tds
))
};
bcx
=
args_res
.bcx
;
let
llargs
=
args_res
.args
;
option
::
may
(
f_res
.tds
)
{|
vals
|
...
...
@@ -2923,7 +2936,7 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
}
ast
::
expr_cast
(
val
,
_
)
{
ret
trans_cast
(
bcx
,
val
,
e
.id
,
dest
);
}
ast
::
expr_call
(
f
,
args
,
_
)
{
ret
trans_call
(
bcx
,
f
,
arg
s
,
e
.id
,
dest
);
ret
trans_call
(
bcx
,
f
,
arg
_exprs
(
args
)
,
e
.id
,
dest
);
}
ast
::
expr_field
(
base
,
_
,
_
)
{
if
dest
==
ignore
{
ret
trans_expr
(
bcx
,
base
,
ignore
);
}
...
...
@@ -2937,9 +2950,9 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
let
origin
=
bcx
.ccx
()
.maps.method_map
.get
(
e
.id
);
let
callee_id
=
ast_util
::
op_expr_callee_id
(
e
);
let
fty
=
node_id_type
(
bcx
,
callee_id
);
ret
trans_call_inner
(
bcx
,
fty
,
{|
bcx
|
ret
trans_call_inner
(
bcx
,
fty
,
expr_ty
(
bcx
,
e
),
{|
bcx
|
impl
::
trans_method_callee
(
bcx
,
callee_id
,
base
,
origin
)
},
[
idx
],
e
.id
,
dest
);
},
arg_exprs
([
idx
])
,
dest
);
}
// These return nothing
...
...
@@ -3037,6 +3050,45 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
assert
dest
==
ignore
;
ret
trans_assign_op
(
bcx
,
e
,
op
,
dst
,
src
);
}
ast
::
expr_new
(
pool
,
alloc_id
,
val
)
{
// First, call pool->alloc(sz, align) to get back a void*. Then, cast
// this memory to the required type and evaluate value into it.
let
ccx
=
bcx
.ccx
();
// Allocate space for the ptr that will be returned from
// `pool.alloc()`:
let
ptr_ty
=
expr_ty
(
bcx
,
e
);
let
{
bcx
,
val
:
ptr_ptr_val
}
=
alloc_ty
(
bcx
,
ptr_ty
);
#
debug
[
"ptr_ty = %s"
,
ty_to_str
(
tcx
,
ptr_ty
)];
#
debug
[
"ptr_ptr_val = %s"
,
val_str
(
ccx
.tn
,
ptr_ptr_val
)];
let
void_ty
=
ty
::
mk_ptr
(
tcx
,
{
ty
:
ty
::
mk_nil
(
tcx
),
mutbl
:
ast
::
m_imm
});
let
voidval
=
{
let
llvoid_ty
=
type_of
(
ccx
,
void_ty
);
PointerCast
(
bcx
,
ptr_ptr_val
,
T_ptr
(
llvoid_ty
))
};
#
debug
[
"voidval = %s"
,
val_str
(
ccx
.tn
,
voidval
)];
let
llval_ty
=
type_of
(
ccx
,
expr_ty
(
bcx
,
val
));
let
args
=
[
llsize_of
(
ccx
,
llval_ty
),
llalign_of
(
ccx
,
llval_ty
)];
let
origin
=
bcx
.ccx
()
.maps.method_map
.get
(
alloc_id
);
let
bcx
=
trans_call_inner
(
bcx
,
node_id_type
(
bcx
,
alloc_id
),
void_ty
,
{|
bcx
|
impl
::
trans_method_callee
(
bcx
,
alloc_id
,
pool
,
origin
)
},
arg_vals
(
args
),
save_in
(
voidval
));
#
debug
[
"dest = %s"
,
dest_str
(
ccx
,
dest
)];
let
ptr_val
=
Load
(
bcx
,
ptr_ptr_val
);
#
debug
[
"ptr_val = %s"
,
val_str
(
ccx
.tn
,
ptr_val
)];
let
bcx
=
trans_expr
(
bcx
,
val
,
save_in
(
ptr_val
));
store_in_dest
(
bcx
,
ptr_val
,
dest
)
}
_
{
bcx
.tcx
()
.sess
.span_bug
(
e
.span
,
"trans_expr reached
\
fall-through case"
);
}
...
...
src/rustc/middle/trans/native.rs
浏览文件 @
cfcbec3c
...
...
@@ -111,27 +111,28 @@ fn all_mem(cls: [mut x86_64_reg_class]) {
}
}
fn
unify
(
cls
:
[
mut
x86_64_reg_class
],
i
:
uint
,
new
:
x86_64_reg_class
)
{
if
cls
[
i
]
==
new
{
fn
unify
(
cls
:
[
mut
x86_64_reg_class
],
i
:
uint
,
newv
:
x86_64_reg_class
)
{
if
cls
[
i
]
==
newv
{
ret
;
}
else
if
cls
[
i
]
==
no_class
{
cls
[
i
]
=
new
;
}
else
if
new
==
no_class
{
cls
[
i
]
=
new
v
;
}
else
if
new
v
==
no_class
{
ret
;
}
else
if
cls
[
i
]
==
memory_class
||
new
==
memory_class
{
}
else
if
cls
[
i
]
==
memory_class
||
new
v
==
memory_class
{
cls
[
i
]
=
memory_class
;
}
else
if
cls
[
i
]
==
integer_class
||
new
==
integer_class
{
}
else
if
cls
[
i
]
==
integer_class
||
new
v
==
integer_class
{
cls
[
i
]
=
integer_class
;
}
else
if
cls
[
i
]
==
x87_class
||
cls
[
i
]
==
x87up_class
||
cls
[
i
]
==
complex_x87_class
||
new
==
x87_class
||
new
==
x87up_class
||
new
==
complex_x87_class
{
new
v
==
x87_class
||
new
v
==
x87up_class
||
new
v
==
complex_x87_class
{
cls
[
i
]
=
memory_class
;
}
else
{
cls
[
i
]
=
new
;
cls
[
i
]
=
new
v
;
}
}
...
...
src/rustc/middle/trans/type_use.rs
浏览文件 @
cfcbec3c
...
...
@@ -168,6 +168,9 @@ fn mark_for_expr(cx: ctx, e: @expr) {
expr_log
(
_
,
_
,
val
)
{
node_type_needs
(
cx
,
use_tydesc
,
val
.id
);
}
expr_new
(
_
,
_
,
v
)
{
node_type_needs
(
cx
,
use_repr
,
v
.id
);
}
expr_for
(
_
,
_
,
_
)
|
expr_do_while
(
_
,
_
)
|
expr_alt
(
_
,
_
,
_
)
|
expr_block
(
_
)
|
expr_if
(
_
,
_
,
_
)
|
expr_while
(
_
,
_
)
|
expr_fail
(
_
)
|
expr_break
|
expr_cont
|
expr_unary
(
_
,
_
)
|
...
...
src/rustc/middle/tstate/ann.rs
浏览文件 @
cfcbec3c
...
...
@@ -183,14 +183,14 @@ fn set_poststate(a: ts_ann, p: poststate) -> bool {
// Set all the bits in p that are set in new
fn
extend_prestate
(
p
:
prestate
,
new
:
poststate
)
->
bool
{
ret
tritv_union
(
p
,
new
);
fn
extend_prestate
(
p
:
prestate
,
new
v
:
poststate
)
->
bool
{
ret
tritv_union
(
p
,
new
v
);
}
// Set all the bits in p that are set in new
fn
extend_poststate
(
p
:
poststate
,
new
:
poststate
)
->
bool
{
ret
tritv_union
(
p
,
new
);
fn
extend_poststate
(
p
:
poststate
,
new
v
:
poststate
)
->
bool
{
ret
tritv_union
(
p
,
new
v
);
}
// Sets the given bit in p to "don't care"
...
...
src/rustc/middle/tstate/auxiliary.rs
浏览文件 @
cfcbec3c
...
...
@@ -709,8 +709,8 @@ fn find_instances(_fcx: fn_ctxt, subst: subst, c: constraint) ->
for
d
:
pred_args
in
*
descs
{
if
args_mention
(
d
.node.args
,
find_in_subst_bool
,
subst
)
{
let
old_bit_num
=
d
.node.bit_num
;
let
new
=
replace
(
subst
,
d
);
alt
find_instance_
(
new
,
*
descs
)
{
let
new
v
=
replace
(
subst
,
d
);
alt
find_instance_
(
new
v
,
*
descs
)
{
some
(
d1
)
{
rslt
+=
[{
from
:
old_bit_num
,
to
:
d1
}];
}
_
{
}
}
...
...
@@ -753,7 +753,7 @@ fn replace(subst: subst, d: pred_args) -> [constr_arg_general_<inst>] {
alt
c
.node
{
carg_ident
(
p
)
{
alt
find_in_subst
(
p
.node
,
subst
)
{
some
(
new
)
{
rslt
+=
[
carg_ident
(
new
)];
}
some
(
new
v
)
{
rslt
+=
[
carg_ident
(
newv
)];
}
_
{
rslt
+=
[
c
.node
];
}
}
}
...
...
src/rustc/middle/tstate/pre_post_conditions.rs
浏览文件 @
cfcbec3c
...
...
@@ -325,6 +325,9 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
clear_pp
(
rslt
);
handle_var
(
fcx
,
rslt
,
e
.id
,
path_to_ident
(
p
));
}
expr_new
(
p
,
_
,
v
)
{
find_pre_post_exprs
(
fcx
,
[
p
,
v
],
e
.id
);
}
expr_log
(
_
,
lvl
,
arg
)
{
find_pre_post_exprs
(
fcx
,
[
lvl
,
arg
],
e
.id
);
}
...
...
src/rustc/middle/tstate/states.rs
浏览文件 @
cfcbec3c
...
...
@@ -355,6 +355,9 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
let
num_constrs
=
num_constraints
(
fcx
.enclosing
);
alt
e
.node
{
expr_new
(
p
,
_
,
v
)
{
ret
find_pre_post_state_two
(
fcx
,
pres
,
p
,
v
,
e
.id
,
oper_pure
);
}
expr_vec
(
elts
,
_
)
{
ret
find_pre_post_state_exprs
(
fcx
,
pres
,
e
.id
,
vec
::
from_elem
(
vec
::
len
(
elts
),
...
...
src/rustc/middle/tstate/tritv.rs
浏览文件 @
cfcbec3c
...
...
@@ -155,8 +155,8 @@ fn trit_and(a: trit, b: trit) -> trit {
// a and b were both dont_care
}
fn
change
(
changed
:
bool
,
old
:
trit
,
new
:
trit
)
->
bool
{
changed
||
new
!=
old
fn
change
(
changed
:
bool
,
old
:
trit
,
new
v
:
trit
)
->
bool
{
changed
||
new
v
!=
old
}
fn
tritv_difference
(
p1
:
t
,
p2
:
t
)
->
bool
{
...
...
@@ -166,9 +166,9 @@ fn tritv_difference(p1: t, p2: t) -> bool {
let
changed
=
false
;
while
i
<
sz
{
let
old
=
tritv_get
(
p1
,
i
);
let
new
=
trit_minus
(
old
,
tritv_get
(
p2
,
i
));
changed
=
change
(
changed
,
old
,
new
);
tritv_set
(
i
,
p1
,
new
);
let
new
v
=
trit_minus
(
old
,
tritv_get
(
p2
,
i
));
changed
=
change
(
changed
,
old
,
new
v
);
tritv_set
(
i
,
p1
,
new
v
);
i
+=
1u
;
}
ret
changed
;
...
...
@@ -181,9 +181,9 @@ fn tritv_union(p1: t, p2: t) -> bool {
let
changed
=
false
;
while
i
<
sz
{
let
old
=
tritv_get
(
p1
,
i
);
let
new
=
trit_or
(
old
,
tritv_get
(
p2
,
i
));
changed
=
change
(
changed
,
old
,
new
);
tritv_set
(
i
,
p1
,
new
);
let
new
v
=
trit_or
(
old
,
tritv_get
(
p2
,
i
));
changed
=
change
(
changed
,
old
,
new
v
);
tritv_set
(
i
,
p1
,
new
v
);
i
+=
1u
;
}
ret
changed
;
...
...
@@ -196,9 +196,9 @@ fn tritv_intersect(p1: t, p2: t) -> bool {
let
changed
=
false
;
while
i
<
sz
{
let
old
=
tritv_get
(
p1
,
i
);
let
new
=
trit_and
(
old
,
tritv_get
(
p2
,
i
));
changed
=
change
(
changed
,
old
,
new
);
tritv_set
(
i
,
p1
,
new
);
let
new
v
=
trit_and
(
old
,
tritv_get
(
p2
,
i
));
changed
=
change
(
changed
,
old
,
new
v
);
tritv_set
(
i
,
p1
,
new
v
);
i
+=
1u
;
}
ret
changed
;
...
...
src/rustc/middle/typeck.rs
浏览文件 @
cfcbec3c
...
...
@@ -1888,6 +1888,12 @@ fn lookup_method_inner(fcx: @fn_ctxt, expr: @ast::expr,
origin
:
method_origin
,
self_sub
:
option
<
self_subst
>
}
>
{
let
tcx
=
fcx
.ccx.tcx
;
#
debug
[
"lookup_method_inner: expr=%s name=%s ty=%s"
,
expr_to_str
(
expr
),
name
,
ty_to_str
(
fcx
.ccx.tcx
,
ty
)];
// First, see whether this is an interface-bounded parameter
alt
ty
::
get
(
ty
)
.struct
{
ty
::
ty_param
(
n
,
did
)
{
...
...
@@ -2870,6 +2876,51 @@ fn get_node(f: spanned<field>) -> field { f.node }
}
}
}
ast
::
expr_new
(
p
,
alloc_id
,
v
)
{
bot
|
=
check_expr
(
fcx
,
p
);
bot
|
=
check_expr
(
fcx
,
v
);
let
p_ty
=
expr_ty
(
tcx
,
p
);
alt
lookup_method
(
fcx
,
p
,
alloc_id
,
"alloc"
,
p_ty
,
[])
{
some
(
origin
)
{
fcx
.ccx.method_map
.insert
(
alloc_id
,
origin
);
// Check that the alloc() method has the expected type, which
// should be fn(sz: uint, align: uint) -> *().
let
expected_ty
=
{
let
ty_uint
=
ty
::
mk_uint
(
tcx
);
let
ty_nilp
=
ty
::
mk_ptr
(
tcx
,
{
ty
:
ty
::
mk_nil
(
tcx
),
mutbl
:
ast
::
m_imm
});
let
m
=
ast
::
expl
(
ty
::
default_arg_mode_for_ty
(
ty_uint
));
ty
::
mk_fn
(
tcx
,
{
proto
:
ast
::
proto_any
,
inputs
:
[{
mode
:
m
,
ty
:
ty_uint
},
{
mode
:
m
,
ty
:
ty_uint
}],
output
:
ty_nilp
,
ret_style
:
ast
::
return_val
,
constraints
:
[]})
};
demand
::
simple
(
fcx
,
expr
.span
,
expected_ty
,
node_id_to_type
(
tcx
,
alloc_id
));
}
none
{
let
t_err
=
resolve_type_vars_if_possible
(
fcx
,
p_ty
);
let
msg
=
#
fmt
[
"no `alloc()` method found for type `%s`"
,
ty_to_str
(
tcx
,
t_err
)];
tcx
.sess
.span_err
(
expr
.span
,
msg
);
}
}
// The region value must have a type like &r.T. The resulting
// memory will be allocated into the region `r`.
let
pool_region
=
region_of
(
fcx
,
p
);
let
v_ty
=
expr_ty
(
tcx
,
v
);
let
res_ty
=
ty
::
mk_rptr
(
tcx
,
pool_region
,
{
ty
:
v_ty
,
mutbl
:
ast
::
m_imm
});
write_ty
(
tcx
,
expr
.id
,
res_ty
);
}
}
if
bot
{
write_ty
(
tcx
,
expr
.id
,
ty
::
mk_bot
(
tcx
));
}
...
...
src/rustc/syntax/ast.rs
浏览文件 @
cfcbec3c
...
...
@@ -325,6 +325,10 @@ enum expr_ {
expr_be
(
@
expr
),
expr_log
(
int
,
@
expr
,
@
expr
),
expr_new
(
/* arena */
@
expr
,
/* id for the alloc() call */
node_id
,
/* value */
@
expr
),
/* just an assert, no significance to typestate */
expr_assert
(
@
expr
),
...
...
src/rustc/syntax/fold.rs
浏览文件 @
cfcbec3c
...
...
@@ -382,6 +382,11 @@ fn fold_field_(field: field, fld: ast_fold) -> field {
let
fold_mac
=
bind
fold_mac_
(
_
,
fld
);
ret
alt
e
{
expr_new
(
p
,
i
,
v
)
{
expr_new
(
fld
.fold_expr
(
p
),
fld
.new_id
(
i
),
fld
.fold_expr
(
v
))
}
expr_vec
(
exprs
,
mutt
)
{
expr_vec
(
fld
.map_exprs
(
fld
.fold_expr
,
exprs
),
mutt
)
}
...
...
src/rustc/syntax/parse/parser.rs
浏览文件 @
cfcbec3c
...
...
@@ -150,7 +150,7 @@ fn bad_expr_word_table() -> hashmap<str, ()> {
"enum"
,
"export"
,
"fail"
,
"fn"
,
"for"
,
"if"
,
"iface"
,
"impl"
,
"import"
,
"let"
,
"log"
,
"loop"
,
"mod"
,
"mut"
,
"mutable"
,
"native"
,
"pure"
,
"resource"
,
"ret"
,
"trait"
,
"type"
,
"unchecked"
,
"unsafe"
,
"while"
]
{
"type"
,
"unchecked"
,
"unsafe"
,
"while"
,
"new"
]
{
words
.insert
(
word
,
());
}
words
...
...
@@ -852,6 +852,13 @@ fn parse_bottom_expr(p: parser) -> pexpr {
let
blk
=
parse_block_tail
(
p
,
lo
,
ast
::
default_blk
);
ret
mk_pexpr
(
p
,
blk
.span.lo
,
blk
.span.hi
,
ast
::
expr_block
(
blk
));
}
}
else
if
eat_word
(
p
,
"new"
)
{
expect
(
p
,
token
::
LPAREN
);
let
r
=
parse_expr
(
p
);
expect
(
p
,
token
::
RPAREN
);
let
v
=
parse_expr
(
p
);
ret
mk_pexpr
(
p
,
lo
,
p
.span.hi
,
ast
::
expr_new
(
r
,
p
.get_id
(),
v
));
}
else
if
eat_word
(
p
,
"if"
)
{
ret
pexpr
(
parse_if_expr
(
p
));
}
else
if
eat_word
(
p
,
"for"
)
{
...
...
src/rustc/syntax/print/pprust.rs
浏览文件 @
cfcbec3c
...
...
@@ -1089,6 +1089,13 @@ fn print_opt(s: ps, expr: option<@ast::expr>) {
word_nbsp
(
s
,
"assert"
);
print_expr
(
s
,
expr
);
}
ast
::
expr_new
(
p
,
_
,
v
)
{
word_nbsp
(
s
,
"new"
);
popen
(
s
);
print_expr
(
s
,
p
);
pclose
(
s
);
print_expr
(
s
,
v
);
}
ast
::
expr_mac
(
m
)
{
print_mac
(
s
,
m
);
}
}
s
.ann
.post
(
ann_node
);
...
...
src/rustc/syntax/visit.rs
浏览文件 @
cfcbec3c
...
...
@@ -315,6 +315,10 @@ fn visit_mac<E>(m: mac, e: E, v: vt<E>) {
fn
visit_expr
<
E
>
(
ex
:
@
expr
,
e
:
E
,
v
:
vt
<
E
>
)
{
alt
ex
.node
{
expr_new
(
pool
,
_
,
val
)
{
v
.visit_expr
(
pool
,
e
,
v
);
v
.visit_expr
(
val
,
e
,
v
);
}
expr_vec
(
es
,
_
)
{
visit_exprs
(
es
,
e
,
v
);
}
expr_rec
(
flds
,
base
)
{
for
f
:
field
in
flds
{
v
.visit_expr
(
f
.node.expr
,
e
,
v
);
}
...
...
src/test/compile-fail/placement-new-bad-method-type.rs
0 → 100644
浏览文件 @
cfcbec3c
import
libc
,
unsafe
;
enum
malloc_pool
=
();
impl
methods
for
malloc_pool
{
fn
alloc
(
sz
:
int
,
align
:
int
)
->
*
()
{
fail
;
}
}
fn
main
()
{
let
p
=
&
malloc_pool
(());
let
x
=
new
(
*
p
)
4u
;
//!^ ERROR mismatched types: expected `fn(uint, uint) -> *()`
}
src/test/run-pass/chan-leak.rs
浏览文件 @
cfcbec3c
...
...
@@ -21,7 +21,7 @@ fn request_task(c: chan<ctx>) {
req
=
recv
(
p
);
}
fn
new
()
->
ctx
{
fn
new
_cx
()
->
ctx
{
let
p
=
port
();
let
ch
=
chan
(
p
);
let
t
=
task
::
spawn
{||
request_task
(
ch
);
};
...
...
@@ -31,7 +31,7 @@ fn new() -> ctx {
}
fn
main
()
{
let
cx
=
new
();
let
cx
=
new
_cx
();
let
p
=
port
::
<
bool
>
();
send
(
cx
,
close
(
chan
(
p
)));
...
...
src/test/run-pass/placement-new-leaky.rs
0 → 100644
浏览文件 @
cfcbec3c
import
libc
,
unsafe
;
enum
malloc_pool
=
();
impl
methods
for
malloc_pool
{
fn
alloc
(
sz
:
uint
,
align
:
uint
)
->
*
()
{
unsafe
{
unsafe
::
reinterpret_cast
(
libc
::
malloc
(
sz
))
}
}
}
fn
main
()
{
let
p
=
&
malloc_pool
(());
let
x
=
new
(
*
p
)
4u
;
io
::
print
(
#
fmt
[
"%u"
,
*
x
]);
assert
*
x
==
4u
;
unsafe
{
libc
::
free
(
unsafe
::
reinterpret_cast
(
x
));
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录