@@ -53,13 +53,13 @@ pub struct Analyzer<'tcx, 'ctx> {
5353}
5454
5555impl < ' tcx , ' ctx > Analyzer < ' tcx , ' ctx > {
56- fn extract_require_annot < T > ( & self , resolver : T ) -> Option < AnnotFormula < T :: Output > >
56+ fn extract_require_annot < T > ( & self , def_id : DefId , resolver : T ) -> Option < AnnotFormula < T :: Output > >
5757 where
5858 T : annot:: Resolver ,
5959 {
6060 let mut require_annot = None ;
6161 for attrs in self . tcx . get_attrs_by_path (
62- self . local_def_id . to_def_id ( ) ,
62+ def_id ,
6363 & analyze:: annot:: requires_path ( ) ,
6464 ) {
6565 if require_annot. is_some ( ) {
@@ -72,13 +72,13 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
7272 require_annot
7373 }
7474
75- fn extract_ensure_annot < T > ( & self , resolver : T ) -> Option < AnnotFormula < T :: Output > >
75+ fn extract_ensure_annot < T > ( & self , def_id : DefId , resolver : T ) -> Option < AnnotFormula < T :: Output > >
7676 where
7777 T : annot:: Resolver ,
7878 {
7979 let mut ensure_annot = None ;
8080 for attrs in self . tcx . get_attrs_by_path (
81- self . local_def_id . to_def_id ( ) ,
81+ def_id ,
8282 & analyze:: annot:: ensures_path ( ) ,
8383 ) {
8484 if ensure_annot. is_some ( ) {
@@ -252,6 +252,14 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
252252 || ( all_params_annotated && has_ret)
253253 }
254254
255+ pub fn get_trait_item ( & mut self ) -> Option < LocalDefId >
256+ {
257+ let impl_item_assoc = self . tcx . opt_associated_item ( self . local_def_id . to_def_id ( ) ) ?;
258+ let trait_item_id = impl_item_assoc. trait_item_def_id . and_then ( |id| id. as_local ( ) ) ?;
259+
260+ Some ( trait_item_id)
261+ }
262+
255263 pub fn expected_ty ( & mut self ) -> rty:: RefinedType {
256264 let sig = self
257265 . ctx
@@ -268,14 +276,26 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
268276 param_resolver. push_param ( input_ident. name , input_ty. to_sort ( ) ) ;
269277 }
270278
271- let mut require_annot = self . extract_require_annot ( & param_resolver) ;
272- let mut ensure_annot = {
273- let output_ty = self . type_builder . build ( sig. output ( ) ) ;
274- let resolver = annot:: StackedResolver :: default ( )
275- . resolver ( analyze:: annot:: ResultResolver :: new ( output_ty. to_sort ( ) ) )
276- . resolver ( ( & param_resolver) . map ( rty:: RefinedTypeVar :: Free ) ) ;
277- self . extract_ensure_annot ( resolver)
278- } ;
279+ let mut require_annot = self . extract_require_annot ( self . local_def_id . to_def_id ( ) , & param_resolver) ;
280+
281+ let output_ty = self . type_builder . build ( sig. output ( ) ) ;
282+ let result_param_resolver = annot:: StackedResolver :: default ( )
283+ . resolver ( analyze:: annot:: ResultResolver :: new ( output_ty. to_sort ( ) ) )
284+ . resolver ( ( & param_resolver) . map ( rty:: RefinedTypeVar :: Free ) ) ;
285+ let mut ensure_annot = self . extract_ensure_annot ( self . local_def_id . to_def_id ( ) , & result_param_resolver) ;
286+
287+ if let Some ( trait_item_id) = self . get_trait_item ( ) {
288+ tracing:: info!( "trait item fonud: {}" , self . tcx. item_name( trait_item_id. into( ) ) . to_string( ) ) ;
289+ let trait_require_annot = self . extract_require_annot ( trait_item_id. into ( ) , & param_resolver) ;
290+ let trait_ensure_annot = self . extract_ensure_annot ( trait_item_id. into ( ) , & result_param_resolver) ;
291+
292+ assert ! ( require_annot. is_none( ) || trait_require_annot. is_none( ) ) ;
293+ require_annot = require_annot. or ( trait_require_annot) ;
294+
295+ assert ! ( ensure_annot. is_none( ) || trait_ensure_annot. is_none( ) ) ;
296+ ensure_annot = ensure_annot. or ( trait_ensure_annot) ;
297+ }
298+
279299 let param_annots = self . extract_param_annots ( & param_resolver) ;
280300 let ret_annot = self . extract_ret_annot ( & param_resolver) ;
281301
0 commit comments