1 use rustc
::ty
::layout
::HasDataLayout
;
2 use rustc
::ty
::layout
::HasParamEnv
;
3 use rustc
::ty
::layout
::HasTyCtxt
;
4 use rustc
::ty
::layout
::LayoutOf
;
5 use rustc
::ty
::layout
::TargetDataLayout
;
6 use rustc
::ty
::layout
::TyLayout
;
7 use rustc
::ty
::ParamEnv
;
10 use rustc_ast
::ast
::Attribute
;
12 use rustc_hir
::def_id
::DefId
;
13 use rustc_hir
::itemlikevisit
::ItemLikeVisitor
;
14 use rustc_hir
::ItemKind
;
15 use rustc_span
::symbol
::sym
;
17 pub fn test_layout(tcx
: TyCtxt
<'_
>) {
18 if tcx
.features().rustc_attrs
{
19 // if the `rustc_attrs` feature is not enabled, don't bother testing layout
20 tcx
.hir().krate().visit_all_item_likes(&mut VarianceTest { tcx }
);
24 struct VarianceTest
<'tcx
> {
28 impl ItemLikeVisitor
<'tcx
> for VarianceTest
<'tcx
> {
29 fn visit_item(&mut self, item
: &'tcx hir
::Item
<'tcx
>) {
30 let item_def_id
= self.tcx
.hir().local_def_id(item
.hir_id
);
32 if let ItemKind
::TyAlias(..) = item
.kind
{
33 for attr
in self.tcx
.get_attrs(item_def_id
).iter() {
34 if attr
.check_name(sym
::rustc_layout
) {
35 self.dump_layout_of(item_def_id
, item
, attr
);
41 fn visit_trait_item(&mut self, _
: &'tcx hir
::TraitItem
<'tcx
>) {}
42 fn visit_impl_item(&mut self, _
: &'tcx hir
::ImplItem
<'tcx
>) {}
45 impl VarianceTest
<'tcx
> {
46 fn dump_layout_of(&self, item_def_id
: DefId
, item
: &hir
::Item
<'tcx
>, attr
: &Attribute
) {
48 let param_env
= self.tcx
.param_env(item_def_id
);
49 let ty
= self.tcx
.type_of(item_def_id
);
50 match self.tcx
.layout_of(param_env
.and(ty
)) {
52 // Check out the `#[rustc_layout(..)]` attribute to tell what to dump.
53 // The `..` are the names of fields to dump.
54 let meta_items
= attr
.meta_item_list().unwrap_or_default();
55 for meta_item
in meta_items
{
56 match meta_item
.name_or_empty() {
58 self.tcx
.sess
.span_err(item
.span
, &format
!("abi: {:?}", ty_layout
.abi
));
64 .span_err(item
.span
, &format
!("align: {:?}", ty_layout
.align
));
70 .span_err(item
.span
, &format
!("size: {:?}", ty_layout
.size
));
73 sym
::homogeneous_aggregate
=> {
74 self.tcx
.sess
.span_err(
77 "homogeneous_aggregate: {:?}",
79 .homogeneous_aggregate(&UnwrapLayoutCx { tcx, param_env }
),
85 self.tcx
.sess
.span_err(
87 &format
!("unrecognized field name `{}`", name
),
94 Err(layout_error
) => {
95 self.tcx
.sess
.span_err(item
.span
, &format
!("layout error: {:?}", layout_error
));
101 struct UnwrapLayoutCx
<'tcx
> {
103 param_env
: ParamEnv
<'tcx
>,
106 impl LayoutOf
for UnwrapLayoutCx
<'tcx
> {
108 type TyLayout
= TyLayout
<'tcx
>;
110 fn layout_of(&self, ty
: Ty
<'tcx
>) -> Self::TyLayout
{
111 self.tcx
.layout_of(self.param_env
.and(ty
)).unwrap()
115 impl HasTyCtxt
<'tcx
> for UnwrapLayoutCx
<'tcx
> {
116 fn tcx(&self) -> TyCtxt
<'tcx
> {
121 impl HasParamEnv
<'tcx
> for UnwrapLayoutCx
<'tcx
> {
122 fn param_env(&self) -> ParamEnv
<'tcx
> {
127 impl HasDataLayout
for UnwrapLayoutCx
<'tcx
> {
128 fn data_layout(&self) -> &TargetDataLayout
{
129 self.tcx
.data_layout()