Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
24587d20
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,发现更多精彩内容 >>
提交
24587d20
编写于
8月 12, 2019
作者:
M
Matthew Jasper
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Pre intern the `Self` parameter type
Use this to simplify the object safety code a bit.
上级
165e460c
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
35 addition
and
47 deletion
+35
-47
src/librustc/traits/object_safety.rs
src/librustc/traits/object_safety.rs
+21
-34
src/librustc/ty/context.rs
src/librustc/ty/context.rs
+5
-4
src/librustc_mir/shim.rs
src/librustc_mir/shim.rs
+1
-1
src/librustc_typeck/astconv.rs
src/librustc_typeck/astconv.rs
+2
-2
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/compare_method.rs
+1
-1
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/check/wfcheck.rs
+1
-1
src/librustc_typeck/collect.rs
src/librustc_typeck/collect.rs
+1
-1
src/librustc_typeck/outlives/implicit_infer.rs
src/librustc_typeck/outlives/implicit_infer.rs
+1
-1
src/librustdoc/clean/mod.rs
src/librustdoc/clean/mod.rs
+1
-1
src/librustdoc/clean/simplify.rs
src/librustdoc/clean/simplify.rs
+1
-1
未找到文件。
src/librustc/traits/object_safety.rs
浏览文件 @
24587d20
...
...
@@ -92,9 +92,8 @@ pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
->
Vec
<
ObjectSafetyViolation
>
{
debug_assert!
(
self
.generics_of
(
trait_def_id
)
.has_self
);
let
self_ty
=
self
.mk_self_type
();
let
violations
=
traits
::
supertrait_def_ids
(
self
,
trait_def_id
)
.filter
(|
&
def_id
|
self
.predicates_reference_self
(
def_id
,
self_ty
,
true
))
.filter
(|
&
def_id
|
self
.predicates_reference_self
(
def_id
,
true
))
.map
(|
_
|
ObjectSafetyViolation
::
SupertraitSelf
)
.collect
();
...
...
@@ -109,11 +108,10 @@ pub fn object_safety_violations(self, trait_def_id: DefId)
->
Vec
<
ObjectSafetyViolation
>
{
debug_assert!
(
self
.generics_of
(
trait_def_id
)
.has_self
);
let
self_ty
=
self
.mk_self_type
();
debug!
(
"object_safety_violations: {:?}"
,
trait_def_id
);
traits
::
supertrait_def_ids
(
self
,
trait_def_id
)
.flat_map
(|
def_id
|
self
.object_safety_violations_for_trait
(
def_id
,
self_ty
))
.flat_map
(|
def_id
|
self
.object_safety_violations_for_trait
(
def_id
))
.collect
()
}
...
...
@@ -123,29 +121,24 @@ pub fn object_safety_violations(self, trait_def_id: DefId)
/// otherwise ensure that they cannot be used when `Self=Trait`.
pub
fn
is_vtable_safe_method
(
self
,
trait_def_id
:
DefId
,
method
:
&
ty
::
AssocItem
)
->
bool
{
debug_assert!
(
self
.generics_of
(
trait_def_id
)
.has_self
);
let
self_ty
=
self
.mk_self_type
();
debug!
(
"is_vtable_safe_method({:?}, {:?})"
,
trait_def_id
,
method
);
// Any method that has a `Self : Sized` requisite can't be called.
if
self
.generics_require_sized_self
(
method
.def_id
,
self_ty
)
{
if
self
.generics_require_sized_self
(
method
.def_id
)
{
return
false
;
}
match
self
.virtual_call_violation_for_method
(
trait_def_id
,
self_ty
,
method
)
{
match
self
.virtual_call_violation_for_method
(
trait_def_id
,
method
)
{
None
|
Some
(
MethodViolationCode
::
WhereClauseReferencesSelf
(
_
))
=>
true
,
Some
(
_
)
=>
false
,
}
}
fn
object_safety_violations_for_trait
(
self
,
trait_def_id
:
DefId
,
self_ty
:
Ty
<
'tcx
>
,
)
->
Vec
<
ObjectSafetyViolation
>
{
fn
object_safety_violations_for_trait
(
self
,
trait_def_id
:
DefId
)
->
Vec
<
ObjectSafetyViolation
>
{
// Check methods for violations.
let
mut
violations
:
Vec
<
_
>
=
self
.associated_items
(
trait_def_id
)
.filter
(|
item
|
item
.kind
==
ty
::
AssocKind
::
Method
)
.filter_map
(|
item
|
self
.object_safety_violation_for_method
(
trait_def_id
,
self_ty
,
&
item
)
self
.object_safety_violation_for_method
(
trait_def_id
,
&
item
)
.map
(|
code
|
ObjectSafetyViolation
::
Method
(
item
.ident.name
,
code
))
)
.filter
(|
violation
|
{
if
let
ObjectSafetyViolation
::
Method
(
_
,
...
...
@@ -167,10 +160,10 @@ fn object_safety_violations_for_trait(
})
.collect
();
// Check the trait itself.
if
self
.trait_has_sized_self
(
trait_def_id
,
self_ty
)
{
if
self
.trait_has_sized_self
(
trait_def_id
)
{
violations
.push
(
ObjectSafetyViolation
::
SizedSelf
);
}
if
self
.predicates_reference_self
(
trait_def_id
,
self_ty
,
false
)
{
if
self
.predicates_reference_self
(
trait_def_id
,
false
)
{
violations
.push
(
ObjectSafetyViolation
::
SupertraitSelf
);
}
...
...
@@ -188,7 +181,6 @@ fn object_safety_violations_for_trait(
fn
predicates_reference_self
(
self
,
trait_def_id
:
DefId
,
self_ty
:
Ty
<
'tcx
>
,
supertraits_only
:
bool
,
)
->
bool
{
let
trait_ref
=
ty
::
Binder
::
dummy
(
ty
::
TraitRef
::
identity
(
self
,
trait_def_id
));
...
...
@@ -197,6 +189,7 @@ fn predicates_reference_self(
}
else
{
self
.predicates_of
(
trait_def_id
)
};
let
self_ty
=
self
.types.self_param
;
let
has_self_ty
=
|
t
:
Ty
<
'tcx
>
|
t
.walk
()
.any
(|
t
|
t
==
self_ty
);
predicates
.predicates
...
...
@@ -241,11 +234,11 @@ fn predicates_reference_self(
})
}
fn
trait_has_sized_self
(
self
,
trait_def_id
:
DefId
,
self_ty
:
Ty
<
'tcx
>
)
->
bool
{
self
.generics_require_sized_self
(
trait_def_id
,
self_ty
)
fn
trait_has_sized_self
(
self
,
trait_def_id
:
DefId
)
->
bool
{
self
.generics_require_sized_self
(
trait_def_id
)
}
fn
generics_require_sized_self
(
self
,
def_id
:
DefId
,
self_ty
:
Ty
<
'tcx
>
)
->
bool
{
fn
generics_require_sized_self
(
self
,
def_id
:
DefId
)
->
bool
{
let
sized_def_id
=
match
self
.lang_items
()
.sized_trait
()
{
Some
(
def_id
)
=>
def_id
,
None
=>
{
return
false
;
/* No Sized trait, can't require it! */
}
...
...
@@ -258,7 +251,7 @@ fn generics_require_sized_self(self, def_id: DefId, self_ty: Ty<'tcx>) -> bool {
.any
(|
predicate
|
match
predicate
{
ty
::
Predicate
::
Trait
(
ref
trait_pred
)
=>
{
trait_pred
.def_id
()
==
sized_def_id
&&
trait_pred
.skip_binder
()
.self_ty
()
==
self_ty
&&
trait_pred
.skip_binder
()
.self_ty
()
.is_param
(
0
)
}
ty
::
Predicate
::
Projection
(
..
)
|
ty
::
Predicate
::
Subtype
(
..
)
|
...
...
@@ -278,17 +271,16 @@ fn generics_require_sized_self(self, def_id: DefId, self_ty: Ty<'tcx>) -> bool {
fn
object_safety_violation_for_method
(
self
,
trait_def_id
:
DefId
,
self_ty
:
Ty
<
'tcx
>
,
method
:
&
ty
::
AssocItem
,
)
->
Option
<
MethodViolationCode
>
{
debug!
(
"object_safety_violation_for_method({:?}, {:?})"
,
trait_def_id
,
method
);
// Any method that has a `Self : Sized` requisite is otherwise
// exempt from the regulations.
if
self
.generics_require_sized_self
(
method
.def_id
,
self_ty
)
{
if
self
.generics_require_sized_self
(
method
.def_id
)
{
return
None
;
}
self
.virtual_call_violation_for_method
(
trait_def_id
,
self_ty
,
method
)
self
.virtual_call_violation_for_method
(
trait_def_id
,
method
)
}
/// Returns `Some(_)` if this method cannot be called on a trait
...
...
@@ -298,7 +290,6 @@ fn object_safety_violation_for_method(
fn
virtual_call_violation_for_method
(
self
,
trait_def_id
:
DefId
,
self_ty
:
Ty
<
'tcx
>
,
method
:
&
ty
::
AssocItem
,
)
->
Option
<
MethodViolationCode
>
{
// The method's first parameter must be named `self`
...
...
@@ -309,15 +300,11 @@ fn virtual_call_violation_for_method(
let
sig
=
self
.fn_sig
(
method
.def_id
);
for
input_ty
in
&
sig
.skip_binder
()
.inputs
()[
1
..
]
{
if
self
.contains_illegal_self_type_reference
(
trait_def_id
,
self_ty
,
input_ty
)
{
if
self
.contains_illegal_self_type_reference
(
trait_def_id
,
input_ty
)
{
return
Some
(
MethodViolationCode
::
ReferencesSelf
);
}
}
if
self
.contains_illegal_self_type_reference
(
trait_def_id
,
self_ty
,
sig
.output
()
.skip_binder
(),
)
{
if
self
.contains_illegal_self_type_reference
(
trait_def_id
,
sig
.output
()
.skip_binder
())
{
return
Some
(
MethodViolationCode
::
ReferencesSelf
);
}
...
...
@@ -336,7 +323,7 @@ fn virtual_call_violation_for_method(
// Do a shallow visit so that `contains_illegal_self_type_reference`
// may apply it's custom visiting.
.visit_tys_shallow
(|
t
|
{
self
.contains_illegal_self_type_reference
(
trait_def_id
,
self_ty
,
t
)
self
.contains_illegal_self_type_reference
(
trait_def_id
,
t
)
})
{
let
span
=
self
.def_span
(
method
.def_id
);
return
Some
(
MethodViolationCode
::
WhereClauseReferencesSelf
(
span
));
...
...
@@ -351,7 +338,7 @@ fn virtual_call_violation_for_method(
// However, this is already considered object-safe. We allow it as a special case here.
// FIXME(mikeyhew) get rid of this `if` statement once `receiver_is_dispatchable` allows
// `Receiver: Unsize<Receiver[Self => dyn Trait]>`
if
receiver_ty
!=
self
_ty
{
if
receiver_ty
!=
self
.types.self_param
{
if
!
self
.receiver_is_dispatchable
(
method
,
receiver_ty
)
{
return
Some
(
MethodViolationCode
::
UndispatchableReceiver
);
}
else
{
...
...
@@ -572,7 +559,7 @@ fn receiver_is_dispatchable(
// Self: Unsize<U>
let
unsize_predicate
=
ty
::
TraitRef
{
def_id
:
unsize_did
,
substs
:
self
.mk_substs_trait
(
self
.
mk_self_type
()
,
&
[
unsized_self_ty
.into
()]),
substs
:
self
.mk_substs_trait
(
self
.
types.self_param
,
&
[
unsized_self_ty
.into
()]),
}
.to_predicate
();
// U: Trait<Arg1, ..., ArgN>
...
...
@@ -628,7 +615,6 @@ fn receiver_is_dispatchable(
fn
contains_illegal_self_type_reference
(
self
,
trait_def_id
:
DefId
,
self_ty
:
Ty
<
'tcx
>
,
ty
:
Ty
<
'tcx
>
,
)
->
bool
{
// This is somewhat subtle. In general, we want to forbid
...
...
@@ -672,6 +658,7 @@ fn contains_illegal_self_type_reference(
let
mut
supertraits
:
Option
<
Vec
<
ty
::
PolyTraitRef
<
'tcx
>>>
=
None
;
let
mut
error
=
false
;
let
self_ty
=
self
.types.self_param
;
ty
.maybe_walk
(|
ty
|
{
match
ty
.sty
{
ty
::
Param
(
_
)
=>
{
...
...
src/librustc/ty/context.rs
浏览文件 @
24587d20
...
...
@@ -173,6 +173,7 @@ pub struct CommonTypes<'tcx> {
pub
f32
:
Ty
<
'tcx
>
,
pub
f64
:
Ty
<
'tcx
>
,
pub
never
:
Ty
<
'tcx
>
,
pub
self_param
:
Ty
<
'tcx
>
,
pub
err
:
Ty
<
'tcx
>
,
/// Dummy type used for the `Self` of a `TraitRef` created for converting
...
...
@@ -915,6 +916,10 @@ fn new(interners: &CtxtInterners<'tcx>) -> CommonTypes<'tcx> {
u128
:
mk
(
Uint
(
ast
::
UintTy
::
U128
)),
f32
:
mk
(
Float
(
ast
::
FloatTy
::
F32
)),
f64
:
mk
(
Float
(
ast
::
FloatTy
::
F64
)),
self_param
:
mk
(
ty
::
Param
(
ty
::
ParamTy
{
index
:
0
,
name
:
kw
::
SelfUpper
.as_interned_str
(),
})),
trait_object_dummy_self
:
mk
(
Infer
(
ty
::
FreshTy
(
0
))),
}
...
...
@@ -2566,10 +2571,6 @@ pub fn mk_const_param(
})
}
#[inline]
pub
fn
mk_self_type
(
self
)
->
Ty
<
'tcx
>
{
self
.mk_ty_param
(
0
,
kw
::
SelfUpper
.as_interned_str
())
}
pub
fn
mk_param_from_def
(
self
,
param
:
&
ty
::
GenericParamDef
)
->
Kind
<
'tcx
>
{
match
param
.kind
{
...
...
src/librustc_mir/shim.rs
浏览文件 @
24587d20
...
...
@@ -710,7 +710,7 @@ fn build_call_shim<'tcx>(
Adjustment
::
DerefMove
=>
{
// fn(Self, ...) -> fn(*mut Self, ...)
let
arg_ty
=
local_decls
[
rcvr_arg
]
.ty
;
debug_assert!
(
tcx
.generics_of
(
def_id
)
.has_self
&&
arg_ty
==
tcx
.
mk_self_type
()
);
debug_assert!
(
tcx
.generics_of
(
def_id
)
.has_self
&&
arg_ty
==
tcx
.
types.self_param
);
local_decls
[
rcvr_arg
]
.ty
=
tcx
.mk_mut_ptr
(
arg_ty
);
Operand
::
Move
(
rcvr_l
.deref
())
...
...
src/librustc_typeck/astconv.rs
浏览文件 @
24587d20
...
...
@@ -636,7 +636,7 @@ fn create_substs_for_ast_path<'a>(&self,
let
default_needs_object_self
=
|
param
:
&
ty
::
GenericParamDef
|
{
if
let
GenericParamDefKind
::
Type
{
has_default
,
..
}
=
param
.kind
{
if
is_object
&&
has_default
&&
has_self
{
let
self_param
=
tcx
.
mk_self_type
()
;
let
self_param
=
tcx
.
types.self_param
;
if
tcx
.at
(
span
)
.type_of
(
param
.def_id
)
.walk
()
.any
(|
ty
|
ty
==
self_param
)
{
// There is no suitable inference default for a type parameter
// that references self, in an object type.
...
...
@@ -2031,7 +2031,7 @@ pub fn res_to_ty(&self,
// `Self` in trait or type alias.
assert_eq!
(
opt_self_ty
,
None
);
self
.prohibit_generics
(
&
path
.segments
);
tcx
.
mk_self_type
()
tcx
.
types.self_param
}
Res
::
SelfTy
(
_
,
Some
(
def_id
))
=>
{
// `Self` in impl (we know the concrete type).
...
...
src/librustc_typeck/check/compare_method.rs
浏览文件 @
24587d20
...
...
@@ -518,7 +518,7 @@ fn compare_self_type<'tcx>(
let
self_string
=
|
method
:
&
ty
::
AssocItem
|
{
let
untransformed_self_ty
=
match
method
.container
{
ty
::
ImplContainer
(
_
)
=>
impl_trait_ref
.self_ty
(),
ty
::
TraitContainer
(
_
)
=>
tcx
.
mk_self_type
()
ty
::
TraitContainer
(
_
)
=>
tcx
.
types.self_param
};
let
self_arg_ty
=
*
tcx
.fn_sig
(
method
.def_id
)
.input
(
0
)
.skip_binder
();
let
param_env
=
ty
::
ParamEnv
::
reveal_all
();
...
...
src/librustc_typeck/check/wfcheck.rs
浏览文件 @
24587d20
...
...
@@ -191,7 +191,7 @@ fn check_associated_item(
let
item
=
fcx
.tcx
.associated_item
(
fcx
.tcx
.hir
()
.local_def_id
(
item_id
));
let
(
mut
implied_bounds
,
self_ty
)
=
match
item
.container
{
ty
::
TraitContainer
(
_
)
=>
(
vec!
[],
fcx
.tcx
.
mk_self_type
()
),
ty
::
TraitContainer
(
_
)
=>
(
vec!
[],
fcx
.tcx.
types.self_param
),
ty
::
ImplContainer
(
def_id
)
=>
(
fcx
.impl_implied_bounds
(
def_id
,
span
),
fcx
.tcx
.type_of
(
def_id
))
};
...
...
src/librustc_typeck/collect.rs
浏览文件 @
24587d20
...
...
@@ -713,7 +713,7 @@ fn super_predicates_of(
let
icx
=
ItemCtxt
::
new
(
tcx
,
trait_def_id
);
// Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`.
let
self_param_ty
=
tcx
.
mk_self_type
()
;
let
self_param_ty
=
tcx
.
types.self_param
;
let
superbounds1
=
AstConv
::
compute_bounds
(
&
icx
,
self_param_ty
,
bounds
,
SizedByDefault
::
No
,
item
.span
);
...
...
src/librustc_typeck/outlives/implicit_infer.rs
浏览文件 @
24587d20
...
...
@@ -211,7 +211,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
substs
,
required_predicates
,
explicit_map
,
Some
(
tcx
.
mk_self_type
()
),
Some
(
tcx
.
types.self_param
),
);
}
}
...
...
src/librustdoc/clean/mod.rs
浏览文件 @
24587d20
...
...
@@ -2303,7 +2303,7 @@ fn clean(&self, cx: &DocContext<'_>) -> Item {
ty
::
ImplContainer
(
def_id
)
=>
{
cx
.tcx
.type_of
(
def_id
)
}
ty
::
TraitContainer
(
_
)
=>
cx
.tcx
.
mk_self_type
()
ty
::
TraitContainer
(
_
)
=>
cx
.tcx.
types.self_param
,
};
let
self_arg_ty
=
*
sig
.input
(
0
)
.skip_binder
();
if
self_arg_ty
==
self_ty
{
...
...
src/librustdoc/clean/simplify.rs
浏览文件 @
24587d20
...
...
@@ -150,7 +150,7 @@ fn trait_is_same_or_supertrait(cx: &DocContext<'_>, child: DefId,
}
let
predicates
=
cx
.tcx
.super_predicates_of
(
child
);
debug_assert!
(
cx
.tcx
.generics_of
(
child
)
.has_self
);
let
self_ty
=
cx
.tcx
.
mk_self_type
()
;
let
self_ty
=
cx
.tcx.
types.self_param
;
predicates
.predicates
.iter
()
.filter_map
(|(
pred
,
_
)|
{
if
let
ty
::
Predicate
::
Trait
(
ref
pred
)
=
*
pred
{
if
pred
.skip_binder
()
.trait_ref
.self_ty
()
==
self_ty
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录