Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
int
Rust
提交
31f4b570
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,发现更多精彩内容 >>
提交
31f4b570
编写于
9月 28, 2017
作者:
W
Wesley Wiser
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Turn `trans_fulfill_obligation` into a query
Part of #44891
上级
f5e036a2
变更
10
显示空白变更内容
内联
并排
Showing
10 changed file
with
226 addition
and
82 deletion
+226
-82
src/librustc/dep_graph/dep_node.rs
src/librustc/dep_graph/dep_node.rs
+2
-1
src/librustc/ich/impls_ty.rs
src/librustc/ich/impls_ty.rs
+126
-0
src/librustc/traits/mod.rs
src/librustc/traits/mod.rs
+2
-0
src/librustc/traits/trans/mod.rs
src/librustc/traits/trans/mod.rs
+64
-74
src/librustc/ty/instance.rs
src/librustc/ty/instance.rs
+1
-2
src/librustc/ty/maps/config.rs
src/librustc/ty/maps/config.rs
+6
-0
src/librustc/ty/maps/keys.rs
src/librustc/ty/maps/keys.rs
+9
-0
src/librustc/ty/maps/mod.rs
src/librustc/ty/maps/mod.rs
+11
-0
src/librustc/ty/maps/plumbing.rs
src/librustc/ty/maps/plumbing.rs
+1
-0
src/librustc_trans/monomorphize.rs
src/librustc_trans/monomorphize.rs
+4
-5
未找到文件。
src/librustc/dep_graph/dep_node.rs
浏览文件 @
31f4b570
...
...
@@ -65,7 +65,7 @@
use
hir
::{
HirId
,
ItemLocalId
};
use
ich
::
Fingerprint
;
use
ty
::{
TyCtxt
,
Instance
,
InstanceDef
,
ParamEnv
And
,
Ty
};
use
ty
::{
TyCtxt
,
Instance
,
InstanceDef
,
ParamEnv
,
ParamEnvAnd
,
PolyTraitRef
,
Ty
};
use
ty
::
subst
::
Substs
;
use
rustc_data_structures
::
stable_hasher
::{
StableHasher
,
HashStable
};
use
ich
::
StableHashingContext
;
...
...
@@ -486,6 +486,7 @@ pub fn fingerprint_needed_for_crate_hash(self) -> bool {
[]
InstanceSymbolName
{
instance
:
Instance
<
'tcx
>
},
[]
SpecializationGraph
(
DefId
),
[]
ObjectSafety
(
DefId
),
[]
FulfillObligation
{
param_env
:
ParamEnv
<
'tcx
>
,
trait_ref
:
PolyTraitRef
<
'tcx
>
},
[]
IsCopy
{
param_env
:
ParamEnvAnd
<
'tcx
,
Ty
<
'tcx
>>
},
[]
IsSized
{
param_env
:
ParamEnvAnd
<
'tcx
,
Ty
<
'tcx
>>
},
...
...
src/librustc/ich/impls_ty.rs
浏览文件 @
31f4b570
...
...
@@ -841,3 +841,129 @@ fn hash_stable<W: StableHasherResult>(&self,
impl_stable_hash_for!
(
tuple_struct
::
middle
::
reachable
::
ReachableSet
{
reachable_set
});
impl
<
'gcx
,
N
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
traits
::
Vtable
<
'gcx
,
N
>
where
N
:
HashStable
<
StableHashingContext
<
'gcx
>>
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
use
traits
::
Vtable
::
*
;
mem
::
discriminant
(
self
)
.hash_stable
(
hcx
,
hasher
);
match
self
{
&
VtableImpl
(
ref
table_impl
)
=>
table_impl
.hash_stable
(
hcx
,
hasher
),
&
VtableDefaultImpl
(
ref
table_def_impl
)
=>
table_def_impl
.hash_stable
(
hcx
,
hasher
),
&
VtableParam
(
ref
table_param
)
=>
table_param
.hash_stable
(
hcx
,
hasher
),
&
VtableObject
(
ref
table_obj
)
=>
table_obj
.hash_stable
(
hcx
,
hasher
),
&
VtableBuiltin
(
ref
table_builtin
)
=>
table_builtin
.hash_stable
(
hcx
,
hasher
),
&
VtableClosure
(
ref
table_closure
)
=>
table_closure
.hash_stable
(
hcx
,
hasher
),
&
VtableFnPointer
(
ref
table_fn_pointer
)
=>
table_fn_pointer
.hash_stable
(
hcx
,
hasher
),
&
VtableGenerator
(
ref
table_generator
)
=>
table_generator
.hash_stable
(
hcx
,
hasher
),
}
}
}
impl
<
'gcx
,
N
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
traits
::
VtableImplData
<
'gcx
,
N
>
where
N
:
HashStable
<
StableHashingContext
<
'gcx
>>
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
let
traits
::
VtableImplData
{
impl_def_id
,
substs
,
ref
nested
,
}
=
*
self
;
impl_def_id
.hash_stable
(
hcx
,
hasher
);
substs
.hash_stable
(
hcx
,
hasher
);
nested
.hash_stable
(
hcx
,
hasher
);
}
}
impl
<
'gcx
,
N
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
traits
::
VtableDefaultImplData
<
N
>
where
N
:
HashStable
<
StableHashingContext
<
'gcx
>>
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
let
traits
::
VtableDefaultImplData
{
trait_def_id
,
ref
nested
,
}
=
*
self
;
trait_def_id
.hash_stable
(
hcx
,
hasher
);
nested
.hash_stable
(
hcx
,
hasher
);
}
}
impl
<
'gcx
,
N
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
traits
::
VtableObjectData
<
'gcx
,
N
>
where
N
:
HashStable
<
StableHashingContext
<
'gcx
>>
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
let
traits
::
VtableObjectData
{
upcast_trait_ref
,
vtable_base
,
ref
nested
,
}
=
*
self
;
upcast_trait_ref
.hash_stable
(
hcx
,
hasher
);
vtable_base
.hash_stable
(
hcx
,
hasher
);
nested
.hash_stable
(
hcx
,
hasher
);
}
}
impl
<
'gcx
,
N
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
traits
::
VtableBuiltinData
<
N
>
where
N
:
HashStable
<
StableHashingContext
<
'gcx
>>
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
let
traits
::
VtableBuiltinData
{
ref
nested
,
}
=
*
self
;
nested
.hash_stable
(
hcx
,
hasher
);
}
}
impl
<
'gcx
,
N
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
traits
::
VtableClosureData
<
'gcx
,
N
>
where
N
:
HashStable
<
StableHashingContext
<
'gcx
>>
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
let
traits
::
VtableClosureData
{
closure_def_id
,
substs
,
ref
nested
,
}
=
*
self
;
closure_def_id
.hash_stable
(
hcx
,
hasher
);
substs
.hash_stable
(
hcx
,
hasher
);
nested
.hash_stable
(
hcx
,
hasher
);
}
}
impl
<
'gcx
,
N
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
traits
::
VtableFnPointerData
<
'gcx
,
N
>
where
N
:
HashStable
<
StableHashingContext
<
'gcx
>>
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
let
traits
::
VtableFnPointerData
{
fn_ty
,
ref
nested
,
}
=
*
self
;
fn_ty
.hash_stable
(
hcx
,
hasher
);
nested
.hash_stable
(
hcx
,
hasher
);
}
}
impl
<
'gcx
,
N
>
HashStable
<
StableHashingContext
<
'gcx
>>
for
traits
::
VtableGeneratorData
<
'gcx
,
N
>
where
N
:
HashStable
<
StableHashingContext
<
'gcx
>>
{
fn
hash_stable
<
W
:
StableHasherResult
>
(
&
self
,
hcx
:
&
mut
StableHashingContext
<
'gcx
>
,
hasher
:
&
mut
StableHasher
<
W
>
)
{
let
traits
::
VtableGeneratorData
{
closure_def_id
,
substs
,
ref
nested
,
}
=
*
self
;
closure_def_id
.hash_stable
(
hcx
,
hasher
);
substs
.hash_stable
(
hcx
,
hasher
);
nested
.hash_stable
(
hcx
,
hasher
);
}
}
src/librustc/traits/mod.rs
浏览文件 @
31f4b570
...
...
@@ -835,6 +835,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
is_object_safe
:
object_safety
::
is_object_safe_provider
,
specialization_graph_of
:
specialize
::
specialization_graph_provider
,
specializes
:
specialize
::
specializes
,
trans_fulfill_obligation
:
trans
::
trans_fulfill_obligation
,
..*
providers
};
}
...
...
@@ -844,6 +845,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
is_object_safe
:
object_safety
::
is_object_safe_provider
,
specialization_graph_of
:
specialize
::
specialization_graph_provider
,
specializes
:
specialize
::
specializes
,
trans_fulfill_obligation
:
trans
::
trans_fulfill_obligation
,
..*
providers
};
}
src/librustc/traits/trans/mod.rs
浏览文件 @
31f4b570
...
...
@@ -17,41 +17,36 @@
use
infer
::
TransNormalize
;
use
std
::
cell
::
RefCell
;
use
std
::
marker
::
PhantomData
;
use
syntax
::
ast
;
use
syntax_pos
::
Span
;
use
syntax_pos
::
DUMMY_SP
;
use
traits
::{
FulfillmentContext
,
Obligation
,
ObligationCause
,
SelectionContext
,
Vtable
};
use
ty
::{
self
,
Ty
,
TyCtxt
};
use
ty
::
subst
::{
Subst
,
Substs
};
use
ty
::
fold
::{
TypeFoldable
,
TypeFolder
};
use
util
::
common
::
MemoizationMap
;
impl
<
'a
,
'tcx
>
TyCtxt
<
'a
,
'tcx
,
'tcx
>
{
/// Attempts to resolve an obligation to a vtable.. The result is
/// a shallow vtable resolution -- meaning that we do not
/// (necessarily) resolve all nested obligations on the impl. Note
/// that type check should guarantee to us that all nested
/// obligations *could be* resolved if we wanted to.
/// Assumes that this is run after the entire crate has been successfully type-checked.
pub
fn
trans_fulfill_obligation
(
self
,
span
:
Span
,
param_env
:
ty
::
ParamEnv
<
'tcx
>
,
trait_ref
:
ty
::
PolyTraitRef
<
'tcx
>
)
/// Attempts to resolve an obligation to a vtable.. The result is
/// a shallow vtable resolution -- meaning that we do not
/// (necessarily) resolve all nested obligations on the impl. Note
/// that type check should guarantee to us that all nested
/// obligations *could be* resolved if we wanted to.
/// Assumes that this is run after the entire crate has been successfully type-checked.
pub
fn
trans_fulfill_obligation
<
'a
,
'tcx
>
(
ty
:
TyCtxt
<
'a
,
'tcx
,
'tcx
>
,
(
param_env
,
trait_ref
):
(
ty
::
ParamEnv
<
'tcx
>
,
ty
::
PolyTraitRef
<
'tcx
>
))
->
Vtable
<
'tcx
,
()
>
{
{
// Remove any references to regions; this helps improve caching.
let
trait_ref
=
self
.erase_regions
(
&
trait_ref
);
let
trait_ref
=
ty
.erase_regions
(
&
trait_ref
);
self
.trans_trait_caches.trait_cache
.memoize
((
param_env
,
trait_ref
),
||
{
debug!
(
"trans::fulfill_obligation(trait_ref={:?}, def_id={:?})"
,
(
param_env
,
trait_ref
),
trait_ref
.def_id
());
// Do the initial selection for the obligation. This yields the
// shallow result we are looking for -- that is, what specific impl.
self
.infer_ctxt
()
.enter
(|
infcx
|
{
ty
.infer_ctxt
()
.enter
(|
infcx
|
{
let
mut
selcx
=
SelectionContext
::
new
(
&
infcx
);
let
obligation_cause
=
ObligationCause
::
misc
(
span
,
ast
::
DUMMY_NODE_ID
);
let
obligation_cause
=
ObligationCause
::
dummy
();
let
obligation
=
Obligation
::
new
(
obligation_cause
,
param_env
,
trait_ref
.to_poly_trait_predicate
());
...
...
@@ -65,15 +60,12 @@ pub fn trans_fulfill_obligation(self,
// leading to an ambiguous result. So report this as an
// overflow bug, since I believe this is the only case
// where ambiguity can result.
de
bug!
(
"Encountered ambiguity selecting `{:?}` during trans,
\
bug!
(
"Encountered ambiguity selecting `{:?}` during trans,
\
presuming due to overflow"
,
trait_ref
);
self
.sess
.span_fatal
(
span
,
"reached the recursion limit during monomorphization
\
(selection ambiguity)"
);
trait_ref
)
}
Err
(
e
)
=>
{
span_bug!
(
span
,
"Encountered error `{:?}` selecting `{:?}` during trans"
,
bug!
(
"Encountered error `{:?}` selecting `{:?}` during trans"
,
e
,
trait_ref
)
}
};
...
...
@@ -88,14 +80,14 @@ pub fn trans_fulfill_obligation(self,
debug!
(
"fulfill_obligation: register_predicate_obligation {:?}"
,
predicate
);
fulfill_cx
.register_predicate_obligation
(
&
infcx
,
predicate
);
});
let
vtable
=
infcx
.drain_fulfillment_cx_or_panic
(
span
,
&
mut
fulfill_cx
,
&
vtable
);
let
vtable
=
infcx
.drain_fulfillment_cx_or_panic
(
DUMMY_SP
,
&
mut
fulfill_cx
,
&
vtable
);
info!
(
"Cache miss: {:?} => {:?}"
,
trait_ref
,
vtable
);
vtable
})
})
}
}
impl
<
'a
,
'tcx
>
TyCtxt
<
'a
,
'tcx
,
'tcx
>
{
/// Monomorphizes a type from the AST by first applying the in-scope
/// substitutions and then normalizing any associated types.
pub
fn
trans_apply_param_substs
<
T
>
(
self
,
...
...
@@ -149,14 +141,12 @@ fn fold_ty(&mut self, ty: Ty<'gcx>) -> Ty<'gcx> {
/// Specializes caches used in trans -- in particular, they assume all
/// types are fully monomorphized and that free regions can be erased.
pub
struct
TransTraitCaches
<
'tcx
>
{
trait_cache
:
RefCell
<
DepTrackingMap
<
TraitSelectionCache
<
'tcx
>>>
,
project_cache
:
RefCell
<
DepTrackingMap
<
ProjectionCache
<
'tcx
>>>
,
}
impl
<
'tcx
>
TransTraitCaches
<
'tcx
>
{
pub
fn
new
(
graph
:
DepGraph
)
->
Self
{
TransTraitCaches
{
trait_cache
:
RefCell
::
new
(
DepTrackingMap
::
new
(
graph
.clone
())),
project_cache
:
RefCell
::
new
(
DepTrackingMap
::
new
(
graph
)),
}
}
...
...
src/librustc/ty/instance.rs
浏览文件 @
31f4b570
...
...
@@ -13,7 +13,6 @@
use
ty
::
subst
::{
Kind
,
Subst
};
use
traits
;
use
syntax
::
abi
::
Abi
;
use
syntax
::
codemap
::
DUMMY_SP
;
use
util
::
ppaux
;
use
std
::
fmt
;
...
...
@@ -212,7 +211,7 @@ fn resolve_associated_item<'a, 'tcx>(
def_id
,
trait_id
,
rcvr_substs
);
let
trait_ref
=
ty
::
TraitRef
::
from_method
(
tcx
,
trait_id
,
rcvr_substs
);
let
vtbl
=
tcx
.trans_fulfill_obligation
(
DUMMY_SP
,
param_env
,
ty
::
Binder
(
trait_ref
));
let
vtbl
=
tcx
.trans_fulfill_obligation
(
(
param_env
,
ty
::
Binder
(
trait_ref
)
));
// Now that we know which impl is being used, we can dispatch to
// the actual function:
...
...
src/librustc/ty/maps/config.rs
浏览文件 @
31f4b570
...
...
@@ -221,6 +221,12 @@ fn describe(tcx: TyCtxt, def_id: DefId) -> String {
}
}
impl
<
'tcx
>
QueryDescription
for
queries
::
trans_fulfill_obligation
<
'tcx
>
{
fn
describe
(
tcx
:
TyCtxt
,
key
:
(
ty
::
ParamEnv
<
'tcx
>
,
ty
::
PolyTraitRef
<
'tcx
>
))
->
String
{
format!
(
"checking if `{}` fulfills its obligations"
,
tcx
.item_path_str
(
key
.1
.def_id
()))
}
}
impl
<
'tcx
>
QueryDescription
for
queries
::
trait_impls_of
<
'tcx
>
{
fn
describe
(
tcx
:
TyCtxt
,
def_id
:
DefId
)
->
String
{
format!
(
"trait impls of `{}`"
,
tcx
.item_path_str
(
def_id
))
...
...
src/librustc/ty/maps/keys.rs
浏览文件 @
31f4b570
...
...
@@ -134,6 +134,15 @@ fn default_span(&self, tcx: TyCtxt) -> Span {
}
}
impl
<
'tcx
>
Key
for
(
ty
::
ParamEnv
<
'tcx
>
,
ty
::
PolyTraitRef
<
'tcx
>
)
{
fn
map_crate
(
&
self
)
->
CrateNum
{
self
.1
.def_id
()
.krate
}
fn
default_span
(
&
self
,
tcx
:
TyCtxt
)
->
Span
{
tcx
.def_span
(
self
.1
.def_id
())
}
}
impl
<
'tcx
>
Key
for
Ty
<
'tcx
>
{
fn
map_crate
(
&
self
)
->
CrateNum
{
LOCAL_CRATE
...
...
src/librustc/ty/maps/mod.rs
浏览文件 @
31f4b570
...
...
@@ -30,6 +30,7 @@
use
mir
;
use
session
::
CompileResult
;
use
session
::
config
::
OutputFilenames
;
use
traits
::
Vtable
;
use
traits
::
specialization_graph
;
use
ty
::{
self
,
CrateInherentImpls
,
Ty
,
TyCtxt
};
use
ty
::
layout
::{
Layout
,
LayoutError
};
...
...
@@ -228,6 +229,8 @@
[]
fn
const_is_rvalue_promotable_to_static
:
ConstIsRvaluePromotableToStatic
(
DefId
)
->
bool
,
[]
fn
is_mir_available
:
IsMirAvailable
(
DefId
)
->
bool
,
[]
fn
trans_fulfill_obligation
:
fulfill_obligation_dep_node
(
(
ty
::
ParamEnv
<
'tcx
>
,
ty
::
PolyTraitRef
<
'tcx
>
))
->
Vtable
<
'tcx
,
()
>
,
[]
fn
trait_impls_of
:
TraitImpls
(
DefId
)
->
Rc
<
ty
::
trait_def
::
TraitImpls
>
,
[]
fn
specialization_graph_of
:
SpecializationGraph
(
DefId
)
->
Rc
<
specialization_graph
::
Graph
>
,
[]
fn
is_object_safe
:
ObjectSafety
(
DefId
)
->
bool
,
...
...
@@ -347,6 +350,14 @@ fn type_param_predicates<'tcx>((item_id, param_id): (DefId, DefId)) -> DepConstr
}
}
fn
fulfill_obligation_dep_node
<
'tcx
>
((
param_env
,
trait_ref
):
(
ty
::
ParamEnv
<
'tcx
>
,
ty
::
PolyTraitRef
<
'tcx
>
))
->
DepConstructor
<
'tcx
>
{
DepConstructor
::
FulfillObligation
{
param_env
,
trait_ref
}
}
fn
coherent_trait_dep_node
<
'tcx
>
((
_
,
def_id
):
(
CrateNum
,
DefId
))
->
DepConstructor
<
'tcx
>
{
DepConstructor
::
CoherenceCheckTrait
(
def_id
)
}
...
...
src/librustc/ty/maps/plumbing.rs
浏览文件 @
31f4b570
...
...
@@ -705,6 +705,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
DepKind
::
TypeParamPredicates
|
DepKind
::
CodegenUnit
|
DepKind
::
CompileCodegenUnit
|
DepKind
::
FulfillObligation
|
// These are just odd
DepKind
::
Null
|
...
...
src/librustc_trans/monomorphize.rs
浏览文件 @
31f4b570
...
...
@@ -15,8 +15,6 @@
use
rustc
::
ty
::
subst
::{
Kind
,
Subst
,
Substs
};
use
rustc
::
ty
::{
self
,
Ty
,
TyCtxt
};
use
syntax
::
codemap
::
DUMMY_SP
;
pub
use
rustc
::
ty
::
Instance
;
fn
fn_once_adapter_instance
<
'a
,
'tcx
>
(
...
...
@@ -110,13 +108,14 @@ pub fn custom_coerce_unsize_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
source_ty
:
Ty
<
'tcx
>
,
target_ty
:
Ty
<
'tcx
>
)
->
CustomCoerceUnsized
{
let
def_id
=
tcx
.lang_items
()
.coerce_unsized_trait
()
.unwrap
();
let
trait_ref
=
ty
::
Binder
(
ty
::
TraitRef
{
def_id
:
tcx
.lang_items
()
.coerce_unsized_trait
()
.unwrap
()
,
def_id
:
def_id
,
substs
:
tcx
.mk_substs_trait
(
source_ty
,
&
[
target_ty
])
});
match
tcx
.trans_fulfill_obligation
(
DUMMY_SP
,
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
),
trait_ref
)
{
match
tcx
.trans_fulfill_obligation
(
(
ty
::
ParamEnv
::
empty
(
traits
::
Reveal
::
All
),
trait_ref
))
{
traits
::
VtableImpl
(
traits
::
VtableImplData
{
impl_def_id
,
..
})
=>
{
tcx
.coerce_unsized_info
(
impl_def_id
)
.custom_kind
.unwrap
()
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录