Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
c2ce2741
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,发现更多精彩内容 >>
提交
c2ce2741
编写于
5月 31, 2012
作者:
N
Niko Matsakis
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
allow mutable vectors and so forth to be used as immutable slices
上级
0470abe1
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
121 addition
and
58 deletion
+121
-58
src/rustc/middle/astencode.rs
src/rustc/middle/astencode.rs
+17
-4
src/rustc/middle/borrowck.rs
src/rustc/middle/borrowck.rs
+3
-3
src/rustc/middle/ty.rs
src/rustc/middle/ty.rs
+8
-1
src/rustc/middle/typeck/infer.rs
src/rustc/middle/typeck/infer.rs
+60
-50
src/test/compile-fail/borrowck-mut-vec-as-imm-slice-bad.rs
src/test/compile-fail/borrowck-mut-vec-as-imm-slice-bad.rs
+17
-0
src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
+16
-0
未找到文件。
src/rustc/middle/astencode.rs
浏览文件 @
c2ce2741
...
@@ -562,6 +562,17 @@ fn tr(xcx: extended_decode_ctxt) -> method_origin {
...
@@ -562,6 +562,17 @@ fn tr(xcx: extended_decode_ctxt) -> method_origin {
}
}
}
}
// ______________________________________________________________________
// Encoding and decoding of borrow
impl
helper
for
ebml
::
ebml_deserializer
{
fn
read_borrow
(
xcx
:
extended_decode_ctxt
)
->
ty
::
borrow
{
let
borrow
=
ty
::
deserialize_borrow
(
self
);
{
scope_id
:
xcx
.tr_id
(
borrow
.scope_id
),
mutbl
:
borrow
.mutbl
}
}
}
// ______________________________________________________________________
// ______________________________________________________________________
// Encoding and decoding vtable_res
// Encoding and decoding vtable_res
...
@@ -866,10 +877,12 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
...
@@ -866,10 +877,12 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
}
}
}
}
option
::
iter
(
tcx
.borrowings
.find
(
id
))
{|
s
|
option
::
iter
(
tcx
.borrowings
.find
(
id
))
{|
borrow
|
ebml_w
.tag
(
c
::
tag_table_borrowings
)
{||
ebml_w
.tag
(
c
::
tag_table_borrowings
)
{||
ebml_w
.id
(
id
);
ebml_w
.id
(
id
);
ebml_w
.wr_tagged_i64
(
c
::
tag_table_val
as
uint
,
s
as
i64
);
ebml_w
.tag
(
c
::
tag_table_val
)
{||
ty
::
serialize_borrow
(
ebml_w
,
borrow
)
}
}
}
}
}
}
}
...
@@ -979,8 +992,8 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
...
@@ -979,8 +992,8 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
dcx
.maps.vtable_map
.insert
(
id
,
dcx
.maps.vtable_map
.insert
(
id
,
val_dsr
.read_vtable_res
(
xcx
));
val_dsr
.read_vtable_res
(
xcx
));
}
else
if
tag
==
(
c
::
tag_table_borrowings
as
uint
)
{
}
else
if
tag
==
(
c
::
tag_table_borrowings
as
uint
)
{
let
scope_id
=
ebml
::
doc_as_i64
(
val_doc
)
as
int
;
let
borrow
=
val_dsr
.read_borrow
(
xcx
)
;
dcx
.tcx.borrowings
.insert
(
id
,
scope_id
);
dcx
.tcx.borrowings
.insert
(
id
,
borrow
);
}
else
{
}
else
{
xcx
.dcx.tcx.sess
.bug
(
xcx
.dcx.tcx.sess
.bug
(
#
fmt
[
"unknown tag found in side tables: %x"
,
tag
]);
#
fmt
[
"unknown tag found in side tables: %x"
,
tag
]);
...
...
src/rustc/middle/borrowck.rs
浏览文件 @
c2ce2741
...
@@ -190,10 +190,10 @@ fn req_loans_in_expr(ex: @ast::expr,
...
@@ -190,10 +190,10 @@ fn req_loans_in_expr(ex: @ast::expr,
let
tcx
=
bccx
.tcx
;
let
tcx
=
bccx
.tcx
;
// If this expression is borrowed, have to ensure it remains valid:
// If this expression is borrowed, have to ensure it remains valid:
for
tcx
.borrowings
.find
(
ex
.id
)
.each
{
|
scope_id
|
for
tcx
.borrowings
.find
(
ex
.id
)
.each
{
|
borrow
|
let
cmt
=
self
.bccx
.cat_borrow_of_expr
(
ex
);
let
cmt
=
self
.bccx
.cat_borrow_of_expr
(
ex
);
let
scope_r
=
ty
::
re_scope
(
scope_id
);
let
scope_r
=
ty
::
re_scope
(
borrow
.
scope_id
);
self
.guarantee_valid
(
cmt
,
m_const
,
scope_r
);
self
.guarantee_valid
(
cmt
,
borrow
.mutbl
,
scope_r
);
}
}
// Special checks for various kinds of expressions:
// Special checks for various kinds of expressions:
...
...
src/rustc/middle/ty.rs
浏览文件 @
c2ce2741
...
@@ -158,6 +158,7 @@
...
@@ -158,6 +158,7 @@
export
ty_sort_str
;
export
ty_sort_str
;
export
normalize_ty
;
export
normalize_ty
;
export
to_str
;
export
to_str
;
export
borrow
,
serialize_borrow
,
deserialize_borrow
;
// Data types
// Data types
...
@@ -204,6 +205,12 @@ enum ast_ty_to_ty_cache_entry {
...
@@ -204,6 +205,12 @@ enum ast_ty_to_ty_cache_entry {
atttce_resolved
(
t
)
/* resolved to a type, irrespective of region */
atttce_resolved
(
t
)
/* resolved to a type, irrespective of region */
}
}
#[auto_serialize]
type
borrow
=
{
scope_id
:
ast
::
node_id
,
mutbl
:
ast
::
mutability
};
type
ctxt
=
type
ctxt
=
@
{
diag
:
syntax
::
diagnostic
::
span_handler
,
@
{
diag
:
syntax
::
diagnostic
::
span_handler
,
interner
:
hashmap
<
intern_key
,
t_box
>
,
interner
:
hashmap
<
intern_key
,
t_box
>
,
...
@@ -239,7 +246,7 @@ enum ast_ty_to_ty_cache_entry {
...
@@ -239,7 +246,7 @@ enum ast_ty_to_ty_cache_entry {
ty_param_bounds
:
hashmap
<
ast
::
node_id
,
param_bounds
>
,
ty_param_bounds
:
hashmap
<
ast
::
node_id
,
param_bounds
>
,
inferred_modes
:
hashmap
<
ast
::
node_id
,
ast
::
mode
>
,
inferred_modes
:
hashmap
<
ast
::
node_id
,
ast
::
mode
>
,
// maps the id of borrowed expr to scope of borrowed ptr
// maps the id of borrowed expr to scope of borrowed ptr
borrowings
:
hashmap
<
ast
::
node_id
,
ast
::
node_id
>
,
borrowings
:
hashmap
<
ast
::
node_id
,
borrow
>
,
normalized_cache
:
hashmap
<
t
,
t
>
};
normalized_cache
:
hashmap
<
t
,
t
>
};
enum
tbox_flag
{
enum
tbox_flag
{
...
...
src/rustc/middle/typeck/infer.rs
浏览文件 @
c2ce2741
...
@@ -157,6 +157,7 @@ fn bar() {
...
@@ -157,6 +157,7 @@ fn bar() {
import
driver
::
session
::
session
;
import
driver
::
session
::
session
;
import
util
::
common
::{
indent
,
indenter
};
import
util
::
common
::{
indent
,
indenter
};
import
ast
::{
unsafe_fn
,
impure_fn
,
pure_fn
,
crust_fn
};
import
ast
::{
unsafe_fn
,
impure_fn
,
pure_fn
,
crust_fn
};
import
ast
::{
m_const
,
m_imm
,
m_mutbl
};
export
infer_ctxt
;
export
infer_ctxt
;
export
new_infer_ctxt
;
export
new_infer_ctxt
;
...
@@ -961,24 +962,27 @@ fn resolve_ty_var(vid: ty_vid) -> ty::t {
...
@@ -961,24 +962,27 @@ fn resolve_ty_var(vid: ty_vid) -> ty::t {
// we just fall back to requiring that a <: b.
// we just fall back to requiring that a <: b.
//
//
// Assuming we have a bound from both sides, we will then examine
// Assuming we have a bound from both sides, we will then examine
// these bounds and see if they have the form (@MT_a, &rb.MT_b)
// these bounds and see if they have the form (@M_a T_a, &rb.M_b T_b)
// (resp. ~MT_a). If they do not, we fall back to subtyping.
// (resp. ~M_a T_a, [M_a T_a], etc). If they do not, we fall back to
// subtyping.
//
//
// If they *do*, then we know that the two types could never be
// If they *do*, then we know that the two types could never be
// subtypes of one another. We will then construct a type @
MT_b and
// subtypes of one another. We will then construct a type @
const T_b
// ensure that type a is a subtype of that. This allows for the
//
and
ensure that type a is a subtype of that. This allows for the
// possibility of assigning from a type like (say) @[mut T1] to a type
// possibility of assigning from a type like (say) @[mut T1] to a type
// &[const T2] where T1 <: T2. Basically we would require that @[mut
// &[T2] where T1 <: T2. This might seem surprising, since the `@`
// T1] <: @[const T2]. Next we require that the region for the
// points at mutable memory but the `&` points at immutable memory.
// enclosing scope be a superregion of the region r. These two checks
// This would in fact be unsound, except for the borrowck, which comes
// together guarantee that the type A would be a subtype of the type B
// later and guarantees that such mutability conversions are safe.
// if the @ were converted to a region r.
// See borrowck for more details. Next we require that the region for
// the enclosing scope be a superregion of the region r.
//
//
// You might wonder why we don't just make the type &e.MT_a where e is
// You might wonder why we don't make the type &e.const T_a where e is
// the enclosing region and check that &e.MT_a <: B. The reason is
// the enclosing region and check that &e.const T_a <: B. The reason
// that the type @MT_a is (generally) just a *lower-bound*, so this
// is that the type of A is (generally) just a *lower-bound*, so this
// would be imposing @MT_a also as the upper-bound on type A. But
// would be imposing that lower-bound also as the upper-bound on type
// this upper-bound might be stricter than what is truly needed.
// A. But this upper-bound might be stricter than what is truly
// needed.
impl
assignment
for
infer_ctxt
{
impl
assignment
for
infer_ctxt
{
fn
assign_tys
(
anmnt
:
assignment
,
a
:
ty
::
t
,
b
:
ty
::
t
)
->
ures
{
fn
assign_tys
(
anmnt
:
assignment
,
a
:
ty
::
t
,
b
:
ty
::
t
)
->
ures
{
...
@@ -1051,35 +1055,39 @@ fn is_borrowable(v: ty::vstore) -> bool {
...
@@ -1051,35 +1055,39 @@ fn is_borrowable(v: ty::vstore) -> bool {
(
some
(
a_bnd
),
some
(
b_bnd
))
{
(
some
(
a_bnd
),
some
(
b_bnd
))
{
alt
(
ty
::
get
(
a_bnd
)
.struct
,
ty
::
get
(
b_bnd
)
.struct
)
{
alt
(
ty
::
get
(
a_bnd
)
.struct
,
ty
::
get
(
b_bnd
)
.struct
)
{
(
ty
::
ty_box
(
mt_a
),
ty
::
ty_rptr
(
r_b
,
mt_b
))
{
(
ty
::
ty_box
(
mt_a
),
ty
::
ty_rptr
(
r_b
,
mt_b
))
{
let
nr_b
=
ty
::
mk_box
(
self
.tcx
,
mt_b
);
let
nr_b
=
ty
::
mk_box
(
self
.tcx
,
{
ty
:
mt_b
.ty
,
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
r_b
)
mutbl
:
m_const
});
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
mt_b
.mutbl
,
r_b
)
}
}
(
ty
::
ty_uniq
(
mt_a
),
ty
::
ty_rptr
(
r_b
,
mt_b
))
{
(
ty
::
ty_uniq
(
mt_a
),
ty
::
ty_rptr
(
r_b
,
mt_b
))
{
let
nr_b
=
ty
::
mk_uniq
(
self
.tcx
,
mt_b
);
let
nr_b
=
ty
::
mk_uniq
(
self
.tcx
,
{
ty
:
mt_b
.ty
,
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
r_b
)
mutbl
:
m_const
});
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
mt_b
.mutbl
,
r_b
)
}
}
(
ty
::
ty_estr
(
vs_a
),
(
ty
::
ty_estr
(
vs_a
),
ty
::
ty_estr
(
ty
::
vstore_slice
(
r_b
)))
ty
::
ty_estr
(
ty
::
vstore_slice
(
r_b
)))
if
is_borrowable
(
vs_a
)
{
if
is_borrowable
(
vs_a
)
{
let
nr_b
=
ty
::
mk_estr
(
self
.tcx
,
vs_a
);
let
nr_b
=
ty
::
mk_estr
(
self
.tcx
,
vs_a
);
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
r_b
)
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
m_imm
,
r_b
)
}
}
(
ty
::
ty_str
,
(
ty
::
ty_str
,
ty
::
ty_estr
(
ty
::
vstore_slice
(
r_b
)))
{
ty
::
ty_estr
(
ty
::
vstore_slice
(
r_b
)))
{
let
nr_b
=
ty
::
mk_str
(
self
.tcx
);
let
nr_b
=
ty
::
mk_str
(
self
.tcx
);
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
r_b
)
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
m_imm
,
r_b
)
}
}
(
ty
::
ty_evec
(
mt_a
,
vs_a
),
(
ty
::
ty_evec
(
mt_a
,
vs_a
),
ty
::
ty_evec
(
mt_b
,
ty
::
vstore_slice
(
r_b
)))
ty
::
ty_evec
(
mt_b
,
ty
::
vstore_slice
(
r_b
)))
if
is_borrowable
(
vs_a
)
{
if
is_borrowable
(
vs_a
)
{
let
nr_b
=
ty
::
mk_evec
(
self
.tcx
,
mt_b
,
vs_a
);
let
nr_b
=
ty
::
mk_evec
(
self
.tcx
,
{
ty
:
mt_b
.ty
,
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
r_b
)
mutbl
:
m_const
},
vs_a
);
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
mt_b
.mutbl
,
r_b
)
}
}
(
ty
::
ty_vec
(
mt_a
),
(
ty
::
ty_vec
(
mt_a
),
ty
::
ty_evec
(
mt_b
,
ty
::
vstore_slice
(
r_b
)))
{
ty
::
ty_evec
(
mt_b
,
ty
::
vstore_slice
(
r_b
)))
{
let
nr_b
=
ty
::
mk_vec
(
self
.tcx
,
mt_b
);
let
nr_b
=
ty
::
mk_vec
(
self
.tcx
,
{
ty
:
mt_b
.ty
,
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
r_b
)
mutbl
:
m_const
});
self
.crosspollinate
(
anmnt
,
a
,
nr_b
,
mt_b
.mutbl
,
r_b
)
}
}
_
{
_
{
self
.sub_tys
(
a
,
b
)
self
.sub_tys
(
a
,
b
)
...
@@ -1093,9 +1101,10 @@ fn is_borrowable(v: ty::vstore) -> bool {
...
@@ -1093,9 +1101,10 @@ fn is_borrowable(v: ty::vstore) -> bool {
}
}
fn
crosspollinate
(
anmnt
:
assignment
,
fn
crosspollinate
(
anmnt
:
assignment
,
a
:
ty
::
t
,
a
:
ty
::
t
,
nr_b
:
ty
::
t
,
nr_b
:
ty
::
t
,
r_b
:
ty
::
region
)
->
ures
{
m
:
ast
::
mutability
,
r_b
:
ty
::
region
)
->
ures
{
#
debug
[
"crosspollinate(anmnt=%?, a=%s, nr_b=%s, r_b=%s)"
,
#
debug
[
"crosspollinate(anmnt=%?, a=%s, nr_b=%s, r_b=%s)"
,
anmnt
,
a
.to_str
(
self
),
nr_b
.to_str
(
self
),
anmnt
,
a
.to_str
(
self
),
nr_b
.to_str
(
self
),
...
@@ -1109,8 +1118,9 @@ fn crosspollinate(anmnt: assignment,
...
@@ -1109,8 +1118,9 @@ fn crosspollinate(anmnt: assignment,
// if successful, add an entry indicating that
// if successful, add an entry indicating that
// borrowing occurred
// borrowing occurred
#
debug
[
"borrowing expression #%?"
,
anmnt
];
#
debug
[
"borrowing expression #%?"
,
anmnt
];
self
.tcx.borrowings
.insert
(
anmnt
.expr_id
,
let
borrow
=
{
scope_id
:
anmnt
.borrow_scope
,
anmnt
.borrow_scope
);
mutbl
:
m
};
self
.tcx.borrowings
.insert
(
anmnt
.expr_id
,
borrow
);
uok
()
uok
()
}
}
}
}
...
@@ -1561,17 +1571,17 @@ fn regions(a: ty::region, b: ty::region) -> cres<ty::region> {
...
@@ -1561,17 +1571,17 @@ fn regions(a: ty::region, b: ty::region) -> cres<ty::region> {
fn
mts
(
a
:
ty
::
mt
,
b
:
ty
::
mt
)
->
cres
<
ty
::
mt
>
{
fn
mts
(
a
:
ty
::
mt
,
b
:
ty
::
mt
)
->
cres
<
ty
::
mt
>
{
#
debug
(
"mts(%s <: %s)"
,
a
.to_str
(
*
self
),
b
.to_str
(
*
self
));
#
debug
(
"mts(%s <: %s)"
,
a
.to_str
(
*
self
),
b
.to_str
(
*
self
));
if
a
.mutbl
!=
b
.mutbl
&&
b
.mutbl
!=
ast
::
m_const
{
if
a
.mutbl
!=
b
.mutbl
&&
b
.mutbl
!=
m_const
{
ret
err
(
ty
::
terr_mutability
);
ret
err
(
ty
::
terr_mutability
);
}
}
alt
b
.mutbl
{
alt
b
.mutbl
{
ast
::
m_mutbl
{
m_mutbl
{
// If supertype is mut, subtype must match exactly
// If supertype is mut, subtype must match exactly
// (i.e., invariant if mut):
// (i.e., invariant if mut):
self
.infcx
()
.eq_tys
(
a
.ty
,
b
.ty
)
.then
{||
ok
(
a
)
}
self
.infcx
()
.eq_tys
(
a
.ty
,
b
.ty
)
.then
{||
ok
(
a
)
}
}
}
ast
::
m_imm
|
ast
::
m_const
{
m_imm
|
m_const
{
// Otherwise we can be covariant:
// Otherwise we can be covariant:
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
_
t
|
ok
(
a
)
}
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
_
t
|
ok
(
a
)
}
}
}
...
@@ -1710,24 +1720,24 @@ fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
...
@@ -1710,24 +1720,24 @@ fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
let
m
=
if
a
.mutbl
==
b
.mutbl
{
let
m
=
if
a
.mutbl
==
b
.mutbl
{
a
.mutbl
a
.mutbl
}
else
{
}
else
{
ast
::
m_const
m_const
};
};
alt
m
{
alt
m
{
ast
::
m_imm
|
ast
::
m_const
{
m_imm
|
m_const
{
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
t
|
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
t
|
ok
({
ty
:
t
,
mutbl
:
m
})
ok
({
ty
:
t
,
mutbl
:
m
})
}
}
}
}
ast
::
m_mutbl
{
m_mutbl
{
self
.infcx
()
.try
{||
self
.infcx
()
.try
{||
self
.infcx
()
.eq_tys
(
a
.ty
,
b
.ty
)
.then
{||
self
.infcx
()
.eq_tys
(
a
.ty
,
b
.ty
)
.then
{||
ok
({
ty
:
a
.ty
,
mutbl
:
m
})
ok
({
ty
:
a
.ty
,
mutbl
:
m
})
}
}
}
.chain_err
{|
_
e
|
}
.chain_err
{|
_
e
|
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
t
|
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
t
|
ok
({
ty
:
t
,
mutbl
:
ast
::
m_const
})
ok
({
ty
:
t
,
mutbl
:
m_const
})
}
}
}
}
}
}
...
@@ -1893,43 +1903,43 @@ fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
...
@@ -1893,43 +1903,43 @@ fn mts(a: ty::mt, b: ty::mt) -> cres<ty::mt> {
alt
(
a
.mutbl
,
b
.mutbl
)
{
alt
(
a
.mutbl
,
b
.mutbl
)
{
// If one side or both is mut, then the GLB must use
// If one side or both is mut, then the GLB must use
// the precise type from the mut side.
// the precise type from the mut side.
(
ast
::
m_mutbl
,
ast
::
m_const
)
{
(
m_mutbl
,
m_const
)
{
sub
(
*
self
)
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
_
t
|
sub
(
*
self
)
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
_
t
|
ok
({
ty
:
a
.ty
,
mutbl
:
ast
::
m_mutbl
})
ok
({
ty
:
a
.ty
,
mutbl
:
m_mutbl
})
}
}
}
}
(
ast
::
m_const
,
ast
::
m_mutbl
)
{
(
m_const
,
m_mutbl
)
{
sub
(
*
self
)
.tys
(
b
.ty
,
a
.ty
)
.chain
{|
_
t
|
sub
(
*
self
)
.tys
(
b
.ty
,
a
.ty
)
.chain
{|
_
t
|
ok
({
ty
:
b
.ty
,
mutbl
:
ast
::
m_mutbl
})
ok
({
ty
:
b
.ty
,
mutbl
:
m_mutbl
})
}
}
}
}
(
ast
::
m_mutbl
,
ast
::
m_mutbl
)
{
(
m_mutbl
,
m_mutbl
)
{
self
.infcx
()
.eq_tys
(
a
.ty
,
b
.ty
)
.then
{||
self
.infcx
()
.eq_tys
(
a
.ty
,
b
.ty
)
.then
{||
ok
({
ty
:
a
.ty
,
mutbl
:
ast
::
m_mutbl
})
ok
({
ty
:
a
.ty
,
mutbl
:
m_mutbl
})
}
}
}
}
// If one side or both is immutable, we can use the GLB of
// If one side or both is immutable, we can use the GLB of
// both sides but mutbl must be `m_imm`.
// both sides but mutbl must be `m_imm`.
(
ast
::
m_imm
,
ast
::
m_const
)
|
(
m_imm
,
m_const
)
|
(
ast
::
m_const
,
ast
::
m_imm
)
|
(
m_const
,
m_imm
)
|
(
ast
::
m_imm
,
ast
::
m_imm
)
{
(
m_imm
,
m_imm
)
{
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
t
|
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
t
|
ok
({
ty
:
t
,
mutbl
:
ast
::
m_imm
})
ok
({
ty
:
t
,
mutbl
:
m_imm
})
}
}
}
}
// If both sides are const, then we can use GLB of both
// If both sides are const, then we can use GLB of both
// sides and mutbl of only `m_const`.
// sides and mutbl of only `m_const`.
(
ast
::
m_const
,
ast
::
m_const
)
{
(
m_const
,
m_const
)
{
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
t
|
self
.tys
(
a
.ty
,
b
.ty
)
.chain
{|
t
|
ok
({
ty
:
t
,
mutbl
:
ast
::
m_const
})
ok
({
ty
:
t
,
mutbl
:
m_const
})
}
}
}
}
// There is no mutual subtype of these combinations.
// There is no mutual subtype of these combinations.
(
ast
::
m_mutbl
,
ast
::
m_imm
)
|
(
m_mutbl
,
m_imm
)
|
(
ast
::
m_imm
,
ast
::
m_mutbl
)
{
(
m_imm
,
m_mutbl
)
{
err
(
ty
::
terr_mutability
)
err
(
ty
::
terr_mutability
)
}
}
}
}
...
...
src/test/compile-fail/borrowck-mut-vec-as-imm-slice-bad.rs
0 → 100644
浏览文件 @
c2ce2741
// xfail-fast (compile-flags unsupported on windows)
// compile-flags:--borrowck=err
fn
want_slice
(
v
:
[
int
]
/&
)
->
int
{
let
mut
sum
=
0
;
for
vec
::
each
(
v
)
{
|
i
|
sum
+=
i
;
}
ret
sum
;
}
fn
has_mut_vec
(
+
v
:
@
[
mut
int
])
->
int
{
want_slice
(
*
v
)
//! ERROR illegal borrow unless pure: creating immutable alias to aliasable, mutable memory
//!^ NOTE impure due to access to impure function
}
fn
main
()
{
assert
has_mut_vec
(
@
[
mut
1
,
2
,
3
])
==
6
;
}
\ No newline at end of file
src/test/run-pass/borrowck-mut-vec-as-imm-slice.rs
0 → 100644
浏览文件 @
c2ce2741
// xfail-fast (compile-flags unsupported on windows)
// compile-flags:--borrowck=err
fn
want_slice
(
v
:
[
int
]
/&
)
->
int
{
let
mut
sum
=
0
;
for
vec
::
each
(
v
)
{
|
i
|
sum
+=
i
;
}
ret
sum
;
}
fn
has_mut_vec
(
+
v
:
[
mut
int
])
->
int
{
want_slice
(
v
)
}
fn
main
()
{
assert
has_mut_vec
([
mut
1
,
2
,
3
])
==
6
;
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录