2 use rustc
::hir
::def_id
::DefId
;
3 use rustc
::hir
::itemlikevisit
::ItemLikeVisitor
;
4 use rustc
::hir
::ItemKind
;
5 use rustc
::ty
::layout
::HasDataLayout
;
6 use rustc
::ty
::layout
::HasTyCtxt
;
7 use rustc
::ty
::layout
::LayoutOf
;
8 use rustc
::ty
::layout
::TargetDataLayout
;
9 use rustc
::ty
::layout
::TyLayout
;
10 use rustc
::ty
::layout
::HasParamEnv
;
11 use rustc
::ty
::ParamEnv
;
13 use rustc
::ty
::TyCtxt
;
14 use syntax
::ast
::Attribute
;
15 use syntax
::symbol
::sym
;
17 pub fn test_layout
<'tcx
>(tcx
: TyCtxt
<'tcx
>) {
18 if tcx
.features().rustc_attrs
{
19 // if the `rustc_attrs` feature is not enabled, don't bother testing layout
22 .visit_all_item_likes(&mut VarianceTest { tcx }
);
26 struct VarianceTest
<'tcx
> {
30 impl ItemLikeVisitor
<'tcx
> for VarianceTest
<'tcx
> {
31 fn visit_item(&mut self, item
: &'tcx hir
::Item
) {
32 let item_def_id
= self.tcx
.hir().local_def_id_from_hir_id(item
.hir_id
);
34 if let ItemKind
::Ty(..) = item
.node
{
35 for attr
in self.tcx
.get_attrs(item_def_id
).iter() {
36 if attr
.check_name(sym
::rustc_layout
) {
37 self.dump_layout_of(item_def_id
, item
, attr
);
43 fn visit_trait_item(&mut self, _
: &'tcx hir
::TraitItem
) {}
44 fn visit_impl_item(&mut self, _
: &'tcx hir
::ImplItem
) {}
47 impl VarianceTest
<'tcx
> {
48 fn dump_layout_of(&self, item_def_id
: DefId
, item
: &hir
::Item
, attr
: &Attribute
) {
50 let param_env
= self.tcx
.param_env(item_def_id
);
51 let ty
= self.tcx
.type_of(item_def_id
);
52 match self.tcx
.layout_of(param_env
.and(ty
)) {
54 // Check out the `#[rustc_layout(..)]` attribute to tell what to dump.
55 // The `..` are the names of fields to dump.
56 let meta_items
= attr
.meta_item_list().unwrap_or_default();
57 for meta_item
in meta_items
{
58 match meta_item
.name_or_empty() {
62 .span_err(item
.span
, &format
!("abi: {:?}", ty_layout
.abi
));
68 .span_err(item
.span
, &format
!("align: {:?}", ty_layout
.align
));
74 .span_err(item
.span
, &format
!("size: {:?}", ty_layout
.size
));
77 sym
::homogeneous_aggregate
=> {
78 self.tcx
.sess
.span_err(
81 "homogeneous_aggregate: {:?}",
83 .homogeneous_aggregate(&UnwrapLayoutCx { tcx, param_env }
),
89 self.tcx
.sess
.span_err(
91 &format
!("unrecognized field name `{}`", name
),
98 Err(layout_error
) => {
101 .span_err(item
.span
, &format
!("layout error: {:?}", layout_error
));
107 struct UnwrapLayoutCx
<'tcx
> {
109 param_env
: ParamEnv
<'tcx
>,
112 impl LayoutOf
for UnwrapLayoutCx
<'tcx
> {
114 type TyLayout
= TyLayout
<'tcx
>;
116 fn layout_of(&self, ty
: Ty
<'tcx
>) -> Self::TyLayout
{
117 self.tcx
.layout_of(self.param_env
.and(ty
)).unwrap()
121 impl HasTyCtxt
<'tcx
> for UnwrapLayoutCx
<'tcx
> {
122 fn tcx(&self) -> TyCtxt
<'tcx
> {
127 impl HasParamEnv
<'tcx
> for UnwrapLayoutCx
<'tcx
> {
128 fn param_env(&self) -> ParamEnv
<'tcx
> {
133 impl HasDataLayout
for UnwrapLayoutCx
<'tcx
> {
134 fn data_layout(&self) -> &TargetDataLayout
{
135 self.tcx
.data_layout()