Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
5d4cce6c
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,发现更多精彩内容 >>
提交
5d4cce6c
编写于
5月 12, 2015
作者:
N
Nick Cameron
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Rebasing
上级
db1b14a1
变更
19
隐藏空白更改
内联
并排
Showing
19 changed file
with
118 addition
and
109 deletion
+118
-109
src/liballoc/rc.rs
src/liballoc/rc.rs
+0
-4
src/libcore/cell.rs
src/libcore/cell.rs
+0
-1
src/libcore/ops.rs
src/libcore/ops.rs
+9
-0
src/libcoretest/cell.rs
src/libcoretest/cell.rs
+12
-11
src/librustc/diagnostics.rs
src/librustc/diagnostics.rs
+0
-2
src/librustc/middle/traits/select.rs
src/librustc/middle/traits/select.rs
+4
-3
src/librustc/middle/traits/util.rs
src/librustc/middle/traits/util.rs
+1
-1
src/librustc/middle/ty.rs
src/librustc/middle/ty.rs
+1
-1
src/librustc_trans/trans/debuginfo/metadata.rs
src/librustc_trans/trans/debuginfo/metadata.rs
+5
-3
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/expr.rs
+2
-2
src/librustc_typeck/check/cast.rs
src/librustc_typeck/check/cast.rs
+30
-25
src/librustc_typeck/check/coercion.rs
src/librustc_typeck/check/coercion.rs
+8
-2
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/regionck.rs
+1
-0
src/librustc_typeck/coherence/mod.rs
src/librustc_typeck/coherence/mod.rs
+15
-26
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/coherence/orphan.rs
+1
-1
src/librustc_typeck/diagnostics.rs
src/librustc_typeck/diagnostics.rs
+3
-3
src/libstd/sync/mutex.rs
src/libstd/sync/mutex.rs
+12
-11
src/libstd/sync/rwlock.rs
src/libstd/sync/rwlock.rs
+12
-11
src/test/compile-fail/fat-ptr-cast.rs
src/test/compile-fail/fat-ptr-cast.rs
+2
-2
未找到文件。
src/liballoc/rc.rs
浏览文件 @
5d4cce6c
...
...
@@ -460,7 +460,6 @@ fn deref(&self) -> &T {
}
#[cfg(stage0)]
// SNAP c64d671
#[unsafe_destructor]
#[stable(feature
=
"rust1"
,
since
=
"1.0.0"
)]
impl
<
T
>
Drop
for
Rc
<
T
>
{
/// Drops the `Rc<T>`.
...
...
@@ -512,7 +511,6 @@ fn drop(&mut self) {
}
#[cfg(not(stage0))]
// SNAP c64d671
#[unsafe_destructor]
#[stable(feature
=
"rust1"
,
since
=
"1.0.0"
)]
impl
<
T
:
?
Sized
>
Drop
for
Rc
<
T
>
{
/// Drops the `Rc<T>`.
...
...
@@ -933,7 +931,6 @@ pub fn upgrade(&self) -> Option<Rc<T>> {
}
#[cfg(stage0)]
// SNAP c64d671
#[unsafe_destructor]
#[stable(feature
=
"rust1"
,
since
=
"1.0.0"
)]
impl
<
T
>
Drop
for
Weak
<
T
>
{
/// Drops the `Weak<T>`.
...
...
@@ -979,7 +976,6 @@ fn drop(&mut self) {
}
#[cfg(not(stage0))]
// SNAP c64d671
#[unsafe_destructor]
#[stable(feature
=
"rust1"
,
since
=
"1.0.0"
)]
impl
<
T
:
?
Sized
>
Drop
for
Weak
<
T
>
{
/// Drops the `Weak<T>`.
...
...
src/libcore/cell.rs
浏览文件 @
5d4cce6c
...
...
@@ -707,5 +707,4 @@ pub fn get(&self) -> *mut T {
#![allow(trivial_casts)]
&
self
.value
as
*
const
T
as
*
mut
T
}
}
src/libcore/ops.rs
浏览文件 @
5d4cce6c
...
...
@@ -1220,24 +1220,33 @@ pub trait CoerceUnsized<T> {
// Empty.
}
// &mut T -> &mut U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
'a
,
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<&
'a
mut
U
>
for
&
'a
mut
T
{}
// &mut T -> &U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
'a
,
'b
:
'a
,
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<&
'a
U
>
for
&
'b
mut
T
{}
// &mut T -> *mut U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
'a
,
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<*
mut
U
>
for
&
'a
mut
T
{}
// &mut T -> *const U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
'a
,
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<*
const
U
>
for
&
'a
mut
T
{}
// &T -> &U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
'a
,
'b
:
'a
,
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<&
'a
U
>
for
&
'b
T
{}
// &T -> *const U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
'a
,
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<*
const
U
>
for
&
'a
T
{}
// *mut T -> *mut U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<*
mut
U
>
for
*
mut
T
{}
// *mut T -> *const U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<*
const
U
>
for
*
mut
T
{}
// *const T -> *const U
#[cfg(not(stage0))]
// SNAP c64d671
impl
<
T
:
?
Sized
+
Unsize
<
U
>
,
U
:
?
Sized
>
CoerceUnsized
<*
const
U
>
for
*
const
T
{}
src/libcoretest/cell.rs
浏览文件 @
5d4cce6c
...
...
@@ -172,14 +172,15 @@ fn unsafe_cell_unsized() {
assert_eq!
(
unsafe
{
&
mut
*
cell
.get
()
},
comp
);
}
#[test]
fn
refcell_unsized
()
{
let
cell
:
&
RefCell
<
[
i32
]
>
=
&
RefCell
::
new
([
1
,
2
,
3
]);
{
let
b
=
&
mut
*
cell
.borrow_mut
();
b
[
0
]
=
4
;
b
[
2
]
=
5
;
}
let
comp
:
&
mut
[
i32
]
=
&
mut
[
4
,
2
,
5
];
assert_eq!
(
&*
cell
.borrow
(),
comp
);
}
// FIXME(#25351) needs deeply nested coercions of DST structs.
// #[test]
// fn refcell_unsized() {
// let cell: &RefCell<[i32]> = &RefCell::new([1, 2, 3]);
// {
// let b = &mut *cell.borrow_mut();
// b[0] = 4;
// b[2] = 5;
// }
// let comp: &mut [i32] = &mut [4, 2, 5];
// assert_eq!(&*cell.borrow(), comp);
// }
src/librustc/diagnostics.rs
浏览文件 @
5d4cce6c
...
...
@@ -808,8 +808,6 @@ struct Foo<T: 'static> {
E0019
,
E0022
,
E0038
,
E0079
,
// enum variant: expected signed integer constant
E0080
,
// enum variant: constant evaluation error
E0109
,
E0110
,
E0134
,
...
...
src/librustc/middle/traits/select.rs
浏览文件 @
5d4cce6c
...
...
@@ -1369,7 +1369,8 @@ fn assemble_candidates_from_object_ty(&mut self,
fn
assemble_candidates_for_unsizing
(
&
mut
self
,
obligation
:
&
TraitObligation
<
'tcx
>
,
candidates
:
&
mut
SelectionCandidateSet
<
'tcx
>
)
{
// TODO is it Ok to skip the binder here?
// It is ok to skip past the higher-ranked binders here because the `match`
// below does not consider regions at all.
let
source
=
self
.infcx
.shallow_resolve
(
*
obligation
.self_ty
()
.skip_binder
());
let
target
=
self
.infcx
.shallow_resolve
(
obligation
.predicate
.0
.input_types
()[
0
]);
...
...
@@ -1494,7 +1495,7 @@ fn candidate_should_be_dropped_in_favor_of<'o>(&mut self,
&
ClosureCandidate
(
..
)
|
&
FnPointerCandidate
(
..
)
|
&
BuiltinObjectCandidate
(
..
)
|
&
&
BuiltinUnsizeCandidate
(
..
)
|
&
BuiltinUnsizeCandidate
(
..
)
|
&
DefaultImplObjectCandidate
(
..
)
|
&
BuiltinCandidate
(
..
)
=>
{
// We have a where-clause so don't go around looking
...
...
@@ -2498,7 +2499,7 @@ fn confirm_builtin_unsize_candidate(&mut self,
ty
::
lookup_field_type_unsubstituted
(
tcx
,
def_id
,
f
.id
)
})
.collect
::
<
Vec
<
_
>>
();
// The last field of the structure has to exist and be a
//
FIXME(#25351)
The last field of the structure has to exist and be a
// type parameter (for now, to avoid tracking edge cases).
let
i
=
if
let
Some
(
&
ty
::
ty_param
(
p
))
=
fields
.last
()
.map
(|
ty
|
&
ty
.sty
)
{
assert
!
(
p
.space
==
TypeSpace
);
...
...
src/librustc/middle/traits/util.rs
浏览文件 @
5d4cce6c
...
...
@@ -377,7 +377,7 @@ pub fn predicate_for_trait_def<'tcx>(
let
trait_ref
=
ty
::
TraitRef
{
def_id
:
trait_def_id
,
substs
:
tcx
.mk_substs
(
Substs
::
new_trait
(
ty_params
,
vec!
[],
param_ty
))
}
)
;
};
predicate_for_trait_ref
(
cause
,
trait_ref
,
recursion_depth
)
}
...
...
src/librustc/middle/ty.rs
浏览文件 @
5d4cce6c
...
...
@@ -4420,7 +4420,7 @@ pub fn deref<'tcx>(ty: Ty<'tcx>, explicit: bool) -> Option<mt<'tcx>> {
pub
fn
type_content
<
'tcx
>
(
ty
:
Ty
<
'tcx
>
)
->
Ty
<
'tcx
>
{
match
ty
.sty
{
ty_uniq
(
ty
)
=>
ty
,
ty_rptr
(
_
,
mt
)
|
ty_ptr
(
mt
)
=>
mt
.ty
,
ty_rptr
(
_
,
mt
)
|
ty_ptr
(
mt
)
=>
mt
.ty
,
_
=>
ty
}
}
...
...
src/librustc_trans/trans/debuginfo/metadata.rs
浏览文件 @
5d4cce6c
...
...
@@ -1058,6 +1058,7 @@ fn new(metadata: DIType, already_stored_in_typemap: bool) -> MetadataCreationRes
}
}
#[derive(Debug)]
enum
MemberOffset
{
FixedMemberOffset
{
bytes
:
usize
},
// For ComputedMemberOffset, the offset is read from the llvm type definition.
...
...
@@ -1066,6 +1067,7 @@ enum MemberOffset {
// Description of a type member, which can either be a regular field (as in
// structs or tuples) or an enum variant.
#[derive(Debug)]
struct
MemberDescription
{
name
:
String
,
llvm_type
:
Type
,
...
...
@@ -1163,13 +1165,13 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
span
:
Span
)
->
RecursiveTypeDescription
<
'tcx
>
{
let
struct_name
=
compute_debuginfo_type_name
(
cx
,
struct_type
,
false
);
let
struct_llvm_type
=
type_of
::
type_of
(
cx
,
struct_type
);
let
struct_llvm_type
=
type_of
::
in_memory_
type_of
(
cx
,
struct_type
);
let
(
containing_scope
,
_
)
=
get_namespace_and_span_for_item
(
cx
,
def_id
);
let
struct_metadata_stub
=
create_struct_stub
(
cx
,
struct_llvm_type
,
&
struct_name
[
..
]
,
&
struct_name
,
unique_type_id
,
containing_scope
);
...
...
@@ -1299,7 +1301,7 @@ fn create_member_descriptions<'a>(&self, cx: &CrateContext<'a, 'tcx>)
set_members_of_composite_type
(
cx
,
variant_type_metadata
,
variant_llvm_type
,
&
member_descriptions
[
..
]
);
&
member_descriptions
);
MemberDescription
{
name
:
""
.to_string
(),
llvm_type
:
variant_llvm_type
,
...
...
src/librustc_trans/trans/expr.rs
浏览文件 @
5d4cce6c
...
...
@@ -487,11 +487,11 @@ fn coerce_unsized<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let
trait_substs
=
Substs
::
erased
(
VecPerParamSpace
::
new
(
vec!
[
target
.ty
],
vec!
[
source
.ty
],
Vec
::
new
()));
let
trait_ref
=
ty
::
Binder
(
Rc
::
new
(
ty
::
TraitRef
{
let
trait_ref
=
ty
::
Binder
(
ty
::
TraitRef
{
def_id
:
langcall
(
bcx
,
Some
(
span
),
"coercion"
,
CoerceUnsizedTraitLangItem
),
substs
:
bcx
.tcx
()
.mk_substs
(
trait_substs
)
})
)
;
});
let
kind
=
match
fulfill_obligation
(
bcx
.ccx
(),
span
,
trait_ref
)
{
traits
::
VtableImpl
(
traits
::
VtableImplData
{
impl_def_id
,
..
})
=>
{
...
...
src/librustc_typeck/check/cast.rs
浏览文件 @
5d4cce6c
...
...
@@ -60,28 +60,29 @@ fn cast_through_integer_err<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let
e
=
&
cast
.expr
;
let
t_e
=
structurally_resolved_type
(
fcx
,
span
,
cast
.expr_ty
);
let
t_1
=
structurally_resolved_type
(
fcx
,
span
,
cast
.cast_ty
);
let
tcx
=
fcx
.tcx
();
// Check for trivial casts.
if
!
ty
::
type_has_ty_infer
(
t_1
)
{
if
let
Ok
(())
=
coercion
::
mk_assignty
(
fcx
,
e
,
t_e
,
t_1
)
{
if
ty
::
type_is_numeric
(
t_1
)
&&
ty
::
type_is_numeric
(
t_e
)
{
fcx
.tcx
()
.sess
.add_lint
(
lint
::
builtin
::
TRIVIAL_NUMERIC_CASTS
,
e
.id
,
span
,
format!
(
"trivial numeric cast: `{}` as `{}`. Cast can be
\
replaced by coercion, this might require type
\
ascription or a temporary variable"
,
fcx
.infcx
()
.ty_to_string
(
t_e
),
fcx
.infcx
()
.ty_to_string
(
t_1
)));
tcx
.sess
.add_lint
(
lint
::
builtin
::
TRIVIAL_NUMERIC_CASTS
,
e
.id
,
span
,
format!
(
"trivial numeric cast: `{}` as `{}`. Cast can be
\
replaced by coercion, this might require type
\
ascription or a temporary variable"
,
fcx
.infcx
()
.ty_to_string
(
t_e
),
fcx
.infcx
()
.ty_to_string
(
t_1
)));
}
else
{
fcx
.tcx
()
.sess
.add_lint
(
lint
::
builtin
::
TRIVIAL_CASTS
,
e
.id
,
span
,
format!
(
"trivial cast: `{}` as `{}`. Cast can be
\
replaced by coercion, this might require type
\
ascription or a temporary variable"
,
fcx
.infcx
()
.ty_to_string
(
t_e
),
fcx
.infcx
()
.ty_to_string
(
t_1
)));
tcx
.sess
.add_lint
(
lint
::
builtin
::
TRIVIAL_CASTS
,
e
.id
,
span
,
format!
(
"trivial cast: `{}` as `{}`. Cast can be
\
replaced by coercion, this might require type
\
ascription or a temporary variable"
,
fcx
.infcx
()
.ty_to_string
(
t_e
),
fcx
.infcx
()
.ty_to_string
(
t_1
)));
}
return
;
}
...
...
@@ -91,14 +92,14 @@ fn cast_through_integer_err<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
let
t_e_is_scalar
=
ty
::
type_is_scalar
(
t_e
);
let
t_e_is_integral
=
ty
::
type_is_integral
(
t_e
);
let
t_e_is_float
=
ty
::
type_is_floating_point
(
t_e
);
let
t_e_is_c_enum
=
ty
::
type_is_c_like_enum
(
fcx
.tcx
()
,
t_e
);
let
t_e_is_c_enum
=
ty
::
type_is_c_like_enum
(
tcx
,
t_e
);
let
t_1_is_scalar
=
ty
::
type_is_scalar
(
t_1
);
let
t_1_is_integral
=
ty
::
type_is_integral
(
t_1
);
let
t_1_is_char
=
ty
::
type_is_char
(
t_1
);
let
t_1_is_bare_fn
=
ty
::
type_is_bare_fn
(
t_1
);
let
t_1_is_float
=
ty
::
type_is_floating_point
(
t_1
);
let
t_1_is_c_enum
=
ty
::
type_is_c_like_enum
(
fcx
.tcx
()
,
t_1
);
let
t_1_is_c_enum
=
ty
::
type_is_c_like_enum
(
tcx
,
t_1
);
let
t1_is_fat_ptr
=
fcx
.type_is_fat_ptr
(
t_1
,
span
);
// casts to scalars other than `char` and `bare fn` are trivial
...
...
@@ -114,7 +115,7 @@ fn cast_through_integer_err<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
},
t_e
,
None
);
}
}
else
if
t_1
.sty
==
ty
::
ty_bool
{
span_err!
(
fcx
.tcx
()
.sess
,
span
,
E0054
,
span_err!
(
tcx
.sess
,
span
,
E0054
,
"cannot cast as `bool`, compare with zero instead"
);
}
else
if
t_e_is_float
&&
(
t_1_is_scalar
||
t_1_is_c_enum
)
&&
!
(
t_1_is_integral
||
t_1_is_float
)
{
...
...
@@ -174,12 +175,16 @@ fn types_compatible<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
}
else
if
t1_is_fat_ptr
{
// FIXME This should be allowed where the lefthandside is also a fat
// pointer and is the same kind of fat pointer, i.e., array to array,
// trait object to trait object.
fcx
.type_error_message
(
span
,
|
actual
|
{
format!
(
"cast to fat pointer: `{}` as `{}`"
,
actual
,
fcx
.infcx
()
.ty_to_string
(
t_1
))
},
t_e
,
None
);
// trait object to trait object. That is a bit looser than the current
// rquirement that they are pointers to the same type.
if
!
(
fcx
.type_is_fat_ptr
(
t_e
,
span
)
&&
ty
::
deref
(
t_1
,
true
)
.unwrap
()
.ty
==
ty
::
deref
(
t_e
,
true
)
.unwrap
()
.ty
)
{
fcx
.type_error_message
(
span
,
|
actual
|
{
format!
(
"cast to fat pointer: `{}` as `{}`"
,
actual
,
fcx
.infcx
()
.ty_to_string
(
t_1
))
},
t_e
,
None
);
}
}
else
if
!
(
t_e_is_scalar
&&
t_1_is_trivial
)
{
fcx
.type_error_message
(
span
,
|
actual
|
{
format!
(
"non-scalar cast: `{}` as `{}`"
,
...
...
src/librustc_typeck/check/coercion.rs
浏览文件 @
5d4cce6c
...
...
@@ -285,14 +285,19 @@ fn coerce_unsized(&self,
// Create an obligation for `Source: CoerceUnsized<Target>`.
let
cause
=
ObligationCause
::
misc
(
self
.origin
.span
(),
self
.fcx.body_id
);
queue
.push_back
(
predicate_for_trait_def
(
self
.tcx
(),
cause
,
coerce_unsized_did
,
0
,
source
,
vec!
[
target
]));
queue
.push_back
(
predicate_for_trait_def
(
self
.tcx
(),
cause
,
coerce_unsized_did
,
0
,
source
,
vec!
[
target
]));
// Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
// emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
// inference might unify those two inner type variables later.
let
traits
=
[
coerce_unsized_did
,
unsize_did
];
while
let
Some
(
obligation
)
=
queue
.pop_front
()
{
debug!
(
"coerce_unsized resolve step: {}"
,
obligation
.repr
(
self
.tcx
()));
let
trait_ref
=
match
obligation
.predicate
{
ty
::
Predicate
::
Trait
(
ref
tr
)
if
traits
.contains
(
&
tr
.def_id
())
=>
{
tr
.clone
()
...
...
@@ -305,6 +310,7 @@ fn coerce_unsized(&self,
match
selcx
.select
(
&
obligation
.with
(
trait_ref
))
{
// Uncertain or unimplemented.
Ok
(
None
)
|
Err
(
traits
::
Unimplemented
)
=>
{
debug!
(
"coerce_unsized: early return - can't prove obligation"
);
return
Err
(
ty
::
terr_mismatch
);
}
...
...
src/librustc_typeck/check/regionck.rs
浏览文件 @
5d4cce6c
...
...
@@ -85,6 +85,7 @@
use
astconv
::
AstConv
;
use
check
::
dropck
;
use
check
::
FnCtxt
;
use
middle
::
free_region
::
FreeRegionMap
;
use
middle
::
implicator
;
use
middle
::
mem_categorization
as
mc
;
use
middle
::
region
::
CodeExtent
;
...
...
src/librustc_typeck/coherence/mod.rs
浏览文件 @
5d4cce6c
...
...
@@ -29,6 +29,7 @@
use
middle
::
ty
::{
ty_uint
,
ty_closure
,
ty_uniq
,
ty_bare_fn
};
use
middle
::
ty
::
ty_projection
;
use
middle
::
ty
;
use
middle
::
free_region
::
FreeRegionMap
;
use
CrateCtxt
;
use
middle
::
infer
::{
self
,
InferCtxt
,
new_infer_ctxt
};
use
std
::
cell
::
RefCell
;
...
...
@@ -439,32 +440,19 @@ fn check_implementations_of_coerce_unsized(&self) {
}
};
let
trait_impls
=
match
tcx
.trait_impls
.borrow
()
.get
(
&
coerce_unsized_trait
)
.cloned
()
{
None
=>
{
debug!
(
"check_implementations_of_coerce_unsized(): no types
\
with implementations of `CoerceUnsized` found"
);
return
}
Some
(
found_impls
)
=>
found_impls
};
let
trait_def
=
ty
::
lookup_trait_def
(
tcx
,
coerce_unsized_trait
);
// Clone first to avoid a double borrow error.
let
trait_impls
=
trait_impls
.borrow
()
.clone
();
for
&
impl_did
in
&
trait_impls
{
trait_def
.for_each_impl
(
tcx
,
|
impl_did
|
{
debug!
(
"check_implementations_of_coerce_unsized: impl_did={}"
,
impl_did
.repr
(
tcx
));
if
impl_did
.krate
!=
ast
::
LOCAL_CRATE
{
debug!
(
"check_implementations_of_coerce_unsized(): impl not
\
in this crate"
);
continue
return
;
}
let
source
=
self
.get_self_type_for_implementation
(
impl_did
)
.ty
;
let
source
=
ty
::
lookup_item_type
(
tcx
,
impl_did
)
.ty
;
let
trait_ref
=
ty
::
impl_id_to_trait_ref
(
self
.crate_context.tcx
,
impl_did
.node
);
let
target
=
*
trait_ref
.substs.types
.get
(
subst
::
TypeSpace
,
0
);
...
...
@@ -507,12 +495,12 @@ fn check_implementations_of_coerce_unsized(&self) {
if
def_id_a
!=
def_id_b
{
let
source_path
=
ty
::
item_path_str
(
tcx
,
def_id_a
);
let
target_path
=
ty
::
item_path_str
(
tcx
,
def_id_b
);
span_err!
(
tcx
.sess
,
span
,
E037
3
,
span_err!
(
tcx
.sess
,
span
,
E037
7
,
"the trait `CoerceUnsized` may only be implemented
\
for a coercion between structures with the same
\
definition; expected {}, found {}"
,
source_path
,
target_path
);
continue
;
return
;
}
let
origin
=
infer
::
Misc
(
span
);
...
...
@@ -532,7 +520,7 @@ fn check_implementations_of_coerce_unsized(&self) {
"the trait `CoerceUnsized` may only be implemented
\
for a coercion between structures with one field
\
being coerced, none found"
);
continue
;
return
;
}
else
if
diff_fields
.len
()
>
1
{
span_err!
(
tcx
.sess
,
span
,
E0375
,
"the trait `CoerceUnsized` may only be implemented
\
...
...
@@ -549,7 +537,7 @@ fn check_implementations_of_coerce_unsized(&self) {
a
.repr
(
tcx
),
b
.repr
(
tcx
))
})
.collect
::
<
Vec
<
_
>>
()
.connect
(
", "
));
continue
;
return
;
}
let
(
i
,
a
,
b
)
=
diff_fields
[
0
];
...
...
@@ -561,7 +549,7 @@ fn check_implementations_of_coerce_unsized(&self) {
span_err!
(
tcx
.sess
,
span
,
E0376
,
"the trait `CoerceUnsized` may only be implemented
\
for a coercion between structures"
);
continue
;
return
;
}
};
...
...
@@ -578,14 +566,15 @@ fn check_implementations_of_coerce_unsized(&self) {
traits
::
report_fulfillment_errors
(
&
infcx
,
&
errors
);
}
// Finally, resolve all regions. This catches wily misuses of lifetime
// parameters.
infcx
.resolve_regions_and_report_errors
(
impl_did
.node
);
// Finally, resolve all regions.
let
mut
free_regions
=
FreeRegionMap
::
new
();
free_regions
.relate_free_regions_from_predicates
(
tcx
,
&
param_env
.caller_bounds
);
infcx
.resolve_regions_and_report_errors
(
&
free_regions
,
impl_did
.node
);
if
let
Some
(
kind
)
=
kind
{
tcx
.custom_coerce_unsized_kinds
.borrow_mut
()
.insert
(
impl_did
,
kind
);
}
}
}
);
}
}
...
...
src/librustc_typeck/coherence/orphan.rs
浏览文件 @
5d4cce6c
...
...
@@ -323,7 +323,7 @@ fn check_item(&self, item: &ast::Item) {
return
;
}
if
Some
(
trait_def_id
)
==
self
.tcx.lang_items
.unsize_trait
()
{
span_err!
(
self
.tcx.sess
,
item
.span
,
E032
3
,
span_err!
(
self
.tcx.sess
,
item
.span
,
E032
8
,
"explicit impls for the `Unsize` trait are not permitted"
);
return
;
}
...
...
src/librustc_typeck/diagnostics.rs
浏览文件 @
5d4cce6c
...
...
@@ -452,13 +452,13 @@ fn foo() -> usize { 12 }
E0369
,
// binary operation `<op>` cannot be applied to types
E0371
,
// impl Trait for Trait is illegal
E0372
,
// impl Trait for Trait where Trait is not object safe
E0373
,
// the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with the same definition
E0374
,
// the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with one field being coerced, none found
E0375
,
// the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with one field being coerced, but multiple
// fields need coercions
E0376
// the trait `CoerceUnsized` may only be implemented for a coercion
E0376
,
// the trait `CoerceUnsized` may only be implemented for a coercion
// between structures
E0377
// the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with the same definition
}
src/libstd/sync/mutex.rs
浏览文件 @
5d4cce6c
...
...
@@ -531,15 +531,16 @@ fn drop(&mut self) {
assert_eq!
(
*
lock
,
2
);
}
#[test]
fn
test_mutex_unsized
()
{
let
mutex
:
&
Mutex
<
[
i32
]
>
=
&
Mutex
::
new
([
1
,
2
,
3
]);
{
let
b
=
&
mut
*
mutex
.lock
()
.unwrap
();
b
[
0
]
=
4
;
b
[
2
]
=
5
;
}
let
comp
:
&
[
i32
]
=
&
[
4
,
2
,
5
];
assert_eq!
(
&*
mutex
.lock
()
.unwrap
(),
comp
);
}
// FIXME(#25351) needs deeply nested coercions of DST structs.
// #[test]
// fn test_mutex_unsized() {
// let mutex: &Mutex<[i32]> = &Mutex::new([1, 2, 3]);
// {
// let b = &mut *mutex.lock().unwrap();
// b[0] = 4;
// b[2] = 5;
// }
// let comp: &[i32] = &[4, 2, 5];
// assert_eq!(&*mutex.lock().unwrap(), comp);
// }
}
src/libstd/sync/rwlock.rs
浏览文件 @
5d4cce6c
...
...
@@ -573,17 +573,18 @@ fn drop(&mut self) {
assert_eq!
(
*
lock
,
2
);
}
#[test]
fn
test_rwlock_unsized
()
{
let
rw
:
&
RwLock
<
[
i32
]
>
=
&
RwLock
::
new
([
1
,
2
,
3
]);
{
let
b
=
&
mut
*
rw
.write
()
.unwrap
();
b
[
0
]
=
4
;
b
[
2
]
=
5
;
}
let
comp
:
&
[
i32
]
=
&
[
4
,
2
,
5
];
assert_eq!
(
&*
rw
.read
()
.unwrap
(),
comp
);
}
// FIXME(#25351) needs deeply nested coercions of DST structs.
// #[test]
// fn test_rwlock_unsized() {
// let rw: &RwLock<[i32]> = &RwLock::new([1, 2, 3]);
// {
// let b = &mut *rw.write().unwrap();
// b[0] = 4;
// b[2] = 5;
// }
// let comp: &[i32] = &[4, 2, 5];
// assert_eq!(&*rw.read().unwrap(), comp);
// }
#[test]
fn
test_rwlock_try_write
()
{
...
...
src/test/compile-fail/fat-ptr-cast.rs
浏览文件 @
5d4cce6c
...
...
@@ -16,8 +16,8 @@ fn main() {
let
a
:
&
[
i32
]
=
&
[
1
,
2
,
3
];
let
b
:
Box
<
[
i32
]
>
=
Box
::
new
([
1
,
2
,
3
]);
a
as
usize
;
//~ ERROR
illegal
cast
b
as
usize
;
//~ ERROR
illegal
cast
a
as
usize
;
//~ ERROR
non-scalar
cast
b
as
usize
;
//~ ERROR
non-scalar
cast
let
a
:
usize
=
42
;
a
as
*
const
[
i32
];
//~ ERROR cast to fat pointer: `usize` as `*const [i32]`
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录