@@ -10,7 +10,7 @@ use crate::rust_to_vir_adts::{check_item_enum, check_item_struct};
10
10
use crate :: rust_to_vir_base:: { hack_check_def_name, hack_get_def_name} ;
11
11
use crate :: rust_to_vir_func:: { check_foreign_item_fn, check_item_fn} ;
12
12
use crate :: util:: unsupported_err_span;
13
- use crate :: { unsupported_err, unsupported_err_unless, unsupported_unless} ;
13
+ use crate :: { err_unless , unsupported_err, unsupported_err_unless, unsupported_unless} ;
14
14
use rustc_ast:: Attribute ;
15
15
use rustc_hir:: {
16
16
Crate , ForeignItem , ForeignItemId , ForeignItemKind , HirId , Item , ItemId , ItemKind , ModuleItems ,
@@ -62,11 +62,52 @@ fn check_item<'tcx>(
62
62
"core" ,
63
63
"marker::StructuralPartialEq"
64
64
)
65
- || hack_check_def_name( tcx, path. res. def_id( ) , "core" , "cmp::PartialEq" ) ,
65
+ || hack_check_def_name( tcx, path. res. def_id( ) , "core" , "cmp::PartialEq" )
66
+ || hack_check_def_name( tcx, path. res. def_id( ) , "builtin" , "Structural" ) ,
66
67
item. span,
67
68
"non_eq_trait_impl" ,
68
69
path
69
70
) ;
71
+ if hack_check_def_name ( tcx, path. res . def_id ( ) , "builtin" , "Structural" ) {
72
+ let ty = {
73
+ // TODO extract to rust_to_vir_base, or use
74
+ // https://doc.rust-lang.org/nightly/nightly-rustc/rustc_typeck/fn.hir_ty_to_ty.html
75
+ // ?
76
+ let def_id = match impll. self_ty . kind {
77
+ rustc_hir:: TyKind :: Path ( QPath :: Resolved ( None , path) ) => {
78
+ path. res . def_id ( )
79
+ }
80
+ _ => panic ! (
81
+ "self type of impl is not resolved: {:?}" ,
82
+ impll. self_ty. kind
83
+ ) ,
84
+ } ;
85
+ tcx. type_of ( def_id)
86
+ } ;
87
+ // TODO: this may be a bit of a hack: to query the TyCtxt for the StructuralEq impl it seems we need
88
+ // a concrete type, so apply ! to all type parameters
89
+ let ty_kind_applied_never =
90
+ if let rustc_middle:: ty:: TyKind :: Adt ( def, substs) = ty. kind ( ) {
91
+ rustc_middle:: ty:: TyKind :: Adt (
92
+ def,
93
+ tcx. mk_substs ( substs. iter ( ) . map ( |g| match g. unpack ( ) {
94
+ rustc_middle:: ty:: subst:: GenericArgKind :: Type ( _) => {
95
+ ( * tcx) . types . never . into ( )
96
+ }
97
+ _ => g,
98
+ } ) ) ,
99
+ )
100
+ } else {
101
+ panic ! ( "Structural impl for non-adt type" ) ;
102
+ } ;
103
+ let ty_applied_never = tcx. mk_ty ( ty_kind_applied_never) ;
104
+ err_unless ! (
105
+ ty_applied_never. is_structural_eq_shallow( tcx) ,
106
+ item. span,
107
+ format!( "Structural impl for non-structural type {:?}" , ty) ,
108
+ ty
109
+ ) ;
110
+ }
70
111
} else {
71
112
unsupported_err_unless ! (
72
113
impll. of_trait. is_none( ) ,
@@ -93,6 +134,15 @@ fn check_item<'tcx>(
93
134
}
94
135
}
95
136
}
137
+ ItemKind :: Const ( _ty, _body_id) => {
138
+ unsupported_err_unless ! (
139
+ hack_get_def_name( tcx, _body_id. hir_id. owner. to_def_id( ) )
140
+ . starts_with( "_DERIVE_builtin_Structural_FOR_" ) ,
141
+ item. span,
142
+ "unsupported const" ,
143
+ item
144
+ ) ;
145
+ }
96
146
_ => {
97
147
unsupported_err ! ( item. span, "unsupported item" , item) ;
98
148
}
@@ -118,7 +168,8 @@ fn check_module<'tcx>(
118
168
unsupported_unless ! (
119
169
def_name == "assert_receiver_is_total_eq"
120
170
|| def_name == "eq"
121
- || def_name == "ne" ,
171
+ || def_name == "ne"
172
+ || def_name == "assert_receiver_is_structural" ,
122
173
"impl definition in module" ,
123
174
id
124
175
) ;
@@ -207,7 +258,8 @@ pub fn crate_to_vir<'tcx>(tcx: TyCtxt<'tcx>, krate: &'tcx Crate<'tcx>) -> Result
207
258
unsupported_unless ! (
208
259
impl_item_ident == "assert_receiver_is_total_eq"
209
260
|| impl_item_ident == "eq"
210
- || impl_item_ident == "ne" ,
261
+ || impl_item_ident == "ne"
262
+ || impl_item_ident == "assert_receiver_is_structural" ,
211
263
"impl definition" ,
212
264
impl_item
213
265
) ;
@@ -217,7 +269,8 @@ pub fn crate_to_vir<'tcx>(tcx: TyCtxt<'tcx>, krate: &'tcx Crate<'tcx>) -> Result
217
269
hack_check_def_name( tcx, * id, "core" , "marker::StructuralEq" )
218
270
|| hack_check_def_name( tcx, * id, "core" , "cmp::Eq" )
219
271
|| hack_check_def_name( tcx, * id, "core" , "marker::StructuralPartialEq" )
220
- || hack_check_def_name( tcx, * id, "core" , "cmp::PartialEq" ) ,
272
+ || hack_check_def_name( tcx, * id, "core" , "cmp::PartialEq" )
273
+ || hack_check_def_name( tcx, * id, "builtin" , "Structural" ) ,
221
274
"non_eq_trait_impl" ,
222
275
id
223
276
) ;
0 commit comments