Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
97214eec
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,发现更多精彩内容 >>
提交
97214eec
编写于
9月 01, 2021
作者:
G
Gary Guo
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add query `own_existential_vtable_entries`
上级
871eb623
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
70 addition
and
45 deletion
+70
-45
compiler/rustc_middle/src/query/mod.rs
compiler/rustc_middle/src/query/mod.rs
+6
-0
compiler/rustc_query_impl/src/keys.rs
compiler/rustc_query_impl/src/keys.rs
+10
-0
compiler/rustc_trait_selection/src/traits/mod.rs
compiler/rustc_trait_selection/src/traits/mod.rs
+37
-17
compiler/rustc_trait_selection/src/traits/util.rs
compiler/rustc_trait_selection/src/traits/util.rs
+17
-28
未找到文件。
compiler/rustc_middle/src/query/mod.rs
浏览文件 @
97214eec
...
@@ -996,6 +996,12 @@
...
@@ -996,6 +996,12 @@
desc
{
|
tcx
|
"checking if item has mir available: `{}`"
,
tcx
.def_path_str
(
key
)
}
desc
{
|
tcx
|
"checking if item has mir available: `{}`"
,
tcx
.def_path_str
(
key
)
}
}
}
query
own_existential_vtable_entries
(
key
:
ty
::
PolyExistentialTraitRef
<
'tcx
>
)
->
&
'tcx
[
DefId
]
{
desc
{
|
tcx
|
"finding all existential vtable entries for trait {}"
,
tcx
.def_path_str
(
key
.def_id
())
}
}
query
vtable_entries
(
key
:
ty
::
PolyTraitRef
<
'tcx
>
)
query
vtable_entries
(
key
:
ty
::
PolyTraitRef
<
'tcx
>
)
->
&
'tcx
[
ty
::
VtblEntry
<
'tcx
>
]
{
->
&
'tcx
[
ty
::
VtblEntry
<
'tcx
>
]
{
desc
{
|
tcx
|
"finding all vtable entries for trait {}"
,
tcx
.def_path_str
(
key
.def_id
())
}
desc
{
|
tcx
|
"finding all vtable entries for trait {}"
,
tcx
.def_path_str
(
key
.def_id
())
}
...
...
compiler/rustc_query_impl/src/keys.rs
浏览文件 @
97214eec
...
@@ -294,6 +294,16 @@ fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
...
@@ -294,6 +294,16 @@ fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
}
}
}
}
impl
<
'tcx
>
Key
for
ty
::
PolyExistentialTraitRef
<
'tcx
>
{
#[inline(always)]
fn
query_crate_is_local
(
&
self
)
->
bool
{
self
.def_id
()
.krate
==
LOCAL_CRATE
}
fn
default_span
(
&
self
,
tcx
:
TyCtxt
<
'_
>
)
->
Span
{
tcx
.def_span
(
self
.def_id
())
}
}
impl
<
'tcx
>
Key
for
(
ty
::
PolyTraitRef
<
'tcx
>
,
ty
::
PolyTraitRef
<
'tcx
>
)
{
impl
<
'tcx
>
Key
for
(
ty
::
PolyTraitRef
<
'tcx
>
,
ty
::
PolyTraitRef
<
'tcx
>
)
{
#[inline(always)]
#[inline(always)]
fn
query_crate_is_local
(
&
self
)
->
bool
{
fn
query_crate_is_local
(
&
self
)
->
bool
{
...
...
compiler/rustc_trait_selection/src/traits/mod.rs
浏览文件 @
97214eec
...
@@ -625,6 +625,31 @@ fn dump_vtable_entries<'tcx>(
...
@@ -625,6 +625,31 @@ fn dump_vtable_entries<'tcx>(
tcx
.sess
.struct_span_err
(
sp
,
&
msg
)
.emit
();
tcx
.sess
.struct_span_err
(
sp
,
&
msg
)
.emit
();
}
}
fn
own_existential_vtable_entries
<
'tcx
>
(
tcx
:
TyCtxt
<
'tcx
>
,
trait_ref
:
ty
::
PolyExistentialTraitRef
<
'tcx
>
,
)
->
&
'tcx
[
DefId
]
{
let
trait_methods
=
tcx
.associated_items
(
trait_ref
.def_id
())
.in_definition_order
()
.filter
(|
item
|
item
.kind
==
ty
::
AssocKind
::
Fn
);
// Now list each method's DefId (for within its trait).
let
own_entries
=
trait_methods
.filter_map
(
move
|
trait_method
|
{
debug!
(
"own_existential_vtable_entry: trait_method={:?}"
,
trait_method
);
let
def_id
=
trait_method
.def_id
;
// Some methods cannot be called on an object; skip those.
if
!
is_vtable_safe_method
(
tcx
,
trait_ref
.def_id
(),
&
trait_method
)
{
debug!
(
"own_existential_vtable_entry: not vtable safe"
);
return
None
;
}
Some
(
def_id
)
});
tcx
.arena
.alloc_from_iter
(
own_entries
.into_iter
())
}
/// Given a trait `trait_ref`, iterates the vtable entries
/// Given a trait `trait_ref`, iterates the vtable entries
/// that come from `trait_ref`, including its supertraits.
/// that come from `trait_ref`, including its supertraits.
fn
vtable_entries
<
'tcx
>
(
fn
vtable_entries
<
'tcx
>
(
...
@@ -641,21 +666,15 @@ fn vtable_entries<'tcx>(
...
@@ -641,21 +666,15 @@ fn vtable_entries<'tcx>(
entries
.extend
(
COMMON_VTABLE_ENTRIES
);
entries
.extend
(
COMMON_VTABLE_ENTRIES
);
}
}
VtblSegment
::
TraitOwnEntries
{
trait_ref
,
emit_vptr
}
=>
{
VtblSegment
::
TraitOwnEntries
{
trait_ref
,
emit_vptr
}
=>
{
let
trait_methods
=
tcx
let
existential_trait_ref
=
trait_ref
.associated_items
(
trait_ref
.def_id
())
.map_bound
(|
trait_ref
|
ty
::
ExistentialTraitRef
::
erase_self_ty
(
tcx
,
trait_ref
));
.in_definition_order
()
.filter
(|
item
|
item
.kind
==
ty
::
AssocKind
::
Fn
);
// Lookup the shape of vtable for the trait.
// Now list each method's DefId and InternalSubsts (for within its trait).
let
own_existential_entries
=
// If the method can never be called from this object, produce `Vacant`.
tcx
.own_existential_vtable_entries
(
existential_trait_ref
);
let
own_entries
=
trait_methods
.filter_map
(
move
|
trait_method
|
{
debug!
(
"vtable_entries: trait_method={:?}"
,
trait_method
);
let
own_entries
=
own_existential_entries
.iter
()
.copied
()
.map
(|
def_id
|
{
let
def_id
=
trait_method
.def_id
;
debug!
(
"vtable_entries: trait_method={:?}"
,
def_id
);
// Some methods cannot be called on an object; skip those.
if
!
is_vtable_safe_method
(
tcx
,
trait_ref
.def_id
(),
&
trait_method
)
{
debug!
(
"vtable_entries: not vtable safe"
);
return
None
;
}
// The method may have some early-bound lifetimes; add regions for those.
// The method may have some early-bound lifetimes; add regions for those.
let
substs
=
trait_ref
.map_bound
(|
trait_ref
|
{
let
substs
=
trait_ref
.map_bound
(|
trait_ref
|
{
...
@@ -681,7 +700,7 @@ fn vtable_entries<'tcx>(
...
@@ -681,7 +700,7 @@ fn vtable_entries<'tcx>(
let
predicates
=
tcx
.predicates_of
(
def_id
)
.instantiate_own
(
tcx
,
substs
);
let
predicates
=
tcx
.predicates_of
(
def_id
)
.instantiate_own
(
tcx
,
substs
);
if
impossible_predicates
(
tcx
,
predicates
.predicates
)
{
if
impossible_predicates
(
tcx
,
predicates
.predicates
)
{
debug!
(
"vtable_entries: predicates do not hold"
);
debug!
(
"vtable_entries: predicates do not hold"
);
return
Some
(
VtblEntry
::
Vacant
)
;
return
VtblEntry
::
Vacant
;
}
}
let
instance
=
ty
::
Instance
::
resolve_for_vtable
(
let
instance
=
ty
::
Instance
::
resolve_for_vtable
(
...
@@ -691,7 +710,7 @@ fn vtable_entries<'tcx>(
...
@@ -691,7 +710,7 @@ fn vtable_entries<'tcx>(
substs
,
substs
,
)
)
.expect
(
"resolution failed during building vtable representation"
);
.expect
(
"resolution failed during building vtable representation"
);
Some
(
VtblEntry
::
Method
(
instance
)
)
VtblEntry
::
Method
(
instance
)
});
});
entries
.extend
(
own_entries
);
entries
.extend
(
own_entries
);
...
@@ -804,6 +823,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
...
@@ -804,6 +823,7 @@ pub fn provide(providers: &mut ty::query::Providers) {
specialization_graph_of
:
specialize
::
specialization_graph_provider
,
specialization_graph_of
:
specialize
::
specialization_graph_provider
,
specializes
:
specialize
::
specializes
,
specializes
:
specialize
::
specializes
,
codegen_fulfill_obligation
:
codegen
::
codegen_fulfill_obligation
,
codegen_fulfill_obligation
:
codegen
::
codegen_fulfill_obligation
,
own_existential_vtable_entries
,
vtable_entries
,
vtable_entries
,
vtable_trait_upcasting_coercion_new_vptr_slot
,
vtable_trait_upcasting_coercion_new_vptr_slot
,
subst_and_check_impossible_predicates
,
subst_and_check_impossible_predicates
,
...
...
compiler/rustc_trait_selection/src/traits/util.rs
浏览文件 @
97214eec
...
@@ -285,17 +285,10 @@ pub fn upcast_choices(
...
@@ -285,17 +285,10 @@ pub fn upcast_choices(
/// that come from `trait_ref`, excluding its supertraits. Used in
/// that come from `trait_ref`, excluding its supertraits. Used in
/// computing the vtable base for an upcast trait of a trait object.
/// computing the vtable base for an upcast trait of a trait object.
pub
fn
count_own_vtable_entries
(
tcx
:
TyCtxt
<
'tcx
>
,
trait_ref
:
ty
::
PolyTraitRef
<
'tcx
>
)
->
usize
{
pub
fn
count_own_vtable_entries
(
tcx
:
TyCtxt
<
'tcx
>
,
trait_ref
:
ty
::
PolyTraitRef
<
'tcx
>
)
->
usize
{
let
mut
entries
=
0
;
let
existential_trait_ref
=
// Count number of methods and add them to the total offset.
trait_ref
.map_bound
(|
trait_ref
|
ty
::
ExistentialTraitRef
::
erase_self_ty
(
tcx
,
trait_ref
));
// Skip over associated types and constants.
let
existential_trait_ref
=
tcx
.erase_regions
(
existential_trait_ref
);
for
trait_item
in
tcx
.associated_items
(
trait_ref
.def_id
())
.in_definition_order
()
{
tcx
.own_existential_vtable_entries
(
existential_trait_ref
)
.len
()
let
is_vtable_safe_method
=
trait_item
.kind
==
ty
::
AssocKind
::
Fn
&&
super
::
is_vtable_safe_method
(
tcx
,
trait_ref
.def_id
(),
trait_item
);
if
is_vtable_safe_method
{
entries
+=
1
;
}
}
entries
}
}
/// Given an upcast trait object described by `object`, returns the
/// Given an upcast trait object described by `object`, returns the
...
@@ -306,25 +299,21 @@ pub fn get_vtable_index_of_object_method<N>(
...
@@ -306,25 +299,21 @@ pub fn get_vtable_index_of_object_method<N>(
object
:
&
super
::
ImplSourceObjectData
<
'tcx
,
N
>
,
object
:
&
super
::
ImplSourceObjectData
<
'tcx
,
N
>
,
method_def_id
:
DefId
,
method_def_id
:
DefId
,
)
->
usize
{
)
->
usize
{
let
existential_trait_ref
=
object
.upcast_trait_ref
.map_bound
(|
trait_ref
|
ty
::
ExistentialTraitRef
::
erase_self_ty
(
tcx
,
trait_ref
));
let
existential_trait_ref
=
tcx
.erase_regions
(
existential_trait_ref
);
// Count number of methods preceding the one we are selecting and
// Count number of methods preceding the one we are selecting and
// add them to the total offset.
// add them to the total offset.
// Skip over associated types and constants, as those aren't stored in the vtable.
let
index
=
tcx
let
mut
entries
=
object
.vtable_base
;
.own_existential_vtable_entries
(
existential_trait_ref
)
let
trait_def_id
=
object
.upcast_trait_ref
.def_id
();
.iter
()
for
trait_item
in
tcx
.associated_items
(
trait_def_id
)
.in_definition_order
()
{
.copied
()
let
is_vtable_safe_method
=
trait_item
.kind
==
ty
::
AssocKind
::
Fn
.position
(|
def_id
|
def_id
==
method_def_id
)
&&
super
::
is_vtable_safe_method
(
tcx
,
trait_def_id
,
trait_item
);
.unwrap_or_else
(||
{
if
trait_item
.def_id
==
method_def_id
{
bug!
(
"get_vtable_index_of_object_method: {:?} was not found"
,
method_def_id
);
// The item with the ID we were given really ought to be a method.
});
assert
!
(
is_vtable_safe_method
);
object
.vtable_base
+
index
return
entries
;
}
if
is_vtable_safe_method
{
entries
+=
1
;
}
}
bug!
(
"get_vtable_index_of_object_method: {:?} was not found"
,
method_def_id
);
}
}
pub
fn
closure_trait_ref_and_return_type
(
pub
fn
closure_trait_ref_and_return_type
(
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录