@@ -5,11 +5,9 @@ use std::collections::HashSet;
55use rustc_hir:: def:: DefKind ;
66use rustc_index:: IndexVec ;
77use rustc_middle:: ty:: { self as mir_ty, TyCtxt } ;
8- use rustc_span:: def_id:: DefId ;
9- use rustc_span:: symbol:: Ident ;
8+ use rustc_span:: def_id:: { DefId , LocalDefId } ;
109
1110use crate :: analyze;
12- use crate :: annot:: { self , AnnotFormula , AnnotParser , ResolverExt as _} ;
1311use crate :: chc;
1412use crate :: refine:: { self , TypeBuilder } ;
1513use crate :: rty:: { self , ClauseBuilderExt as _} ;
@@ -34,188 +32,31 @@ impl<'tcx, 'ctx> Analyzer<'tcx, 'ctx> {
3432 fn refine_local_defs ( & mut self ) {
3533 for local_def_id in self . tcx . mir_keys ( ( ) ) {
3634 if self . tcx . def_kind ( * local_def_id) . is_fn_like ( ) {
37- self . refine_fn_def ( local_def_id. to_def_id ( ) ) ;
35+ self . refine_fn_def ( * local_def_id) ;
3836 }
3937 }
4038 }
4139
42- fn extract_require_annot < T > (
43- & self ,
44- resolver : T ,
45- def_id : DefId ,
46- ) -> Option < AnnotFormula < T :: Output > >
47- where
48- T : annot:: Resolver ,
49- {
50- let mut require_annot = None ;
51- for attrs in self
52- . tcx
53- . get_attrs_by_path ( def_id, & analyze:: annot:: requires_path ( ) )
54- {
55- if require_annot. is_some ( ) {
56- unimplemented ! ( ) ;
57- }
58- let ts = analyze:: annot:: extract_annot_tokens ( attrs. clone ( ) ) ;
59- let require = AnnotParser :: new ( & resolver) . parse_formula ( ts) . unwrap ( ) ;
60- require_annot = Some ( require) ;
61- }
62- require_annot
63- }
40+ #[ tracing:: instrument( skip( self ) , fields( def_id = %self . tcx. def_path_str( local_def_id) ) ) ]
41+ fn refine_fn_def ( & mut self , local_def_id : LocalDefId ) {
42+ let mut analyzer = self . ctx . local_def_analyzer ( local_def_id) ;
6443
65- fn extract_ensure_annot < T > ( & self , resolver : T , def_id : DefId ) -> Option < AnnotFormula < T :: Output > >
66- where
67- T : annot:: Resolver ,
68- {
69- let mut ensure_annot = None ;
70- for attrs in self
71- . tcx
72- . get_attrs_by_path ( def_id, & analyze:: annot:: ensures_path ( ) )
73- {
74- if ensure_annot. is_some ( ) {
75- unimplemented ! ( ) ;
76- }
77- let ts = analyze:: annot:: extract_annot_tokens ( attrs. clone ( ) ) ;
78- let ensure = AnnotParser :: new ( & resolver) . parse_formula ( ts) . unwrap ( ) ;
79- ensure_annot = Some ( ensure) ;
44+ if analyzer. is_annotated_as_trusted ( ) {
45+ assert ! ( analyzer. is_fully_annotated( ) ) ;
46+ self . trusted . insert ( local_def_id. to_def_id ( ) ) ;
8047 }
81- ensure_annot
82- }
8348
84- fn extract_param_annots < T > (
85- & self ,
86- resolver : T ,
87- def_id : DefId ,
88- ) -> Vec < ( Ident , rty:: RefinedType < T :: Output > ) >
89- where
90- T : annot:: Resolver ,
91- {
92- let mut param_annots = Vec :: new ( ) ;
93- for attrs in self
49+ let sig = self
9450 . tcx
95- . get_attrs_by_path ( def_id, & analyze:: annot:: param_path ( ) )
96- {
97- let ts = analyze:: annot:: extract_annot_tokens ( attrs. clone ( ) ) ;
98- let ( ident, ts) = analyze:: annot:: split_param ( & ts) ;
99- let param = AnnotParser :: new ( & resolver) . parse_rty ( ts) . unwrap ( ) ;
100- param_annots. push ( ( ident, param) ) ;
101- }
102- param_annots
103- }
104-
105- fn extract_ret_annot < T > (
106- & self ,
107- resolver : T ,
108- def_id : DefId ,
109- ) -> Option < rty:: RefinedType < T :: Output > >
110- where
111- T : annot:: Resolver ,
112- {
113- let mut ret_annot = None ;
114- for attrs in self
115- . tcx
116- . get_attrs_by_path ( def_id, & analyze:: annot:: ret_path ( ) )
117- {
118- if ret_annot. is_some ( ) {
119- unimplemented ! ( ) ;
120- }
121- let ts = analyze:: annot:: extract_annot_tokens ( attrs. clone ( ) ) ;
122- let ret = AnnotParser :: new ( & resolver) . parse_rty ( ts) . unwrap ( ) ;
123- ret_annot = Some ( ret) ;
124- }
125- ret_annot
126- }
127-
128- #[ tracing:: instrument( skip( self ) , fields( def_id = %self . tcx. def_path_str( def_id) ) ) ]
129- fn refine_fn_def ( & mut self , def_id : DefId ) {
130- let sig = self . tcx . fn_sig ( def_id) ;
131- let sig = sig. instantiate_identity ( ) . skip_binder ( ) ;
132- if let Some ( rty) = self . fn_def_ty_with_sig ( def_id, sig) {
133- self . ctx . register_def ( def_id, rty) ;
134- } else {
135- self . ctx . register_deferred_def ( def_id) ;
136- }
137- }
138-
139- pub fn fn_def_ty_with_sig (
140- & mut self ,
141- def_id : DefId ,
142- sig : mir_ty:: FnSig < ' tcx > ,
143- ) -> Option < rty:: RefinedType > {
144- let mut param_resolver = analyze:: annot:: ParamResolver :: default ( ) ;
145- for ( input_ident, input_ty) in self . tcx . fn_arg_names ( def_id) . iter ( ) . zip ( sig. inputs ( ) ) {
146- let input_ty = TypeBuilder :: new ( self . tcx , def_id) . build ( * input_ty) ;
147- param_resolver. push_param ( input_ident. name , input_ty. to_sort ( ) ) ;
148- }
149-
150- let mut require_annot = self . extract_require_annot ( & param_resolver, def_id) ;
151- let mut ensure_annot = {
152- let output_ty = TypeBuilder :: new ( self . tcx , def_id) . build ( sig. output ( ) ) ;
153- let resolver = annot:: StackedResolver :: default ( )
154- . resolver ( analyze:: annot:: ResultResolver :: new ( output_ty. to_sort ( ) ) )
155- . resolver ( ( & param_resolver) . map ( rty:: RefinedTypeVar :: Free ) ) ;
156- self . extract_ensure_annot ( resolver, def_id)
157- } ;
158- let param_annots = self . extract_param_annots ( & param_resolver, def_id) ;
159- let ret_annot = self . extract_ret_annot ( & param_resolver, def_id) ;
160-
161- if self
162- . tcx
163- . get_attrs_by_path ( def_id, & analyze:: annot:: callable_path ( ) )
164- . next ( )
165- . is_some ( )
166- {
167- if require_annot. is_some ( ) || ensure_annot. is_some ( ) {
168- unimplemented ! ( ) ;
169- }
170-
171- require_annot = Some ( AnnotFormula :: top ( ) ) ;
172- ensure_annot = Some ( AnnotFormula :: top ( ) ) ;
173- }
174-
175- assert ! ( require_annot. is_none( ) || param_annots. is_empty( ) ) ;
176- assert ! ( ensure_annot. is_none( ) || ret_annot. is_none( ) ) ;
177-
178- if self
179- . tcx
180- . get_attrs_by_path ( def_id, & analyze:: annot:: trusted_path ( ) )
181- . next ( )
182- . is_some ( )
183- {
184- assert ! ( require_annot. is_some( ) || !param_annots. is_empty( ) ) ;
185- assert ! ( ensure_annot. is_some( ) || ret_annot. is_some( ) ) ;
186- self . trusted . insert ( def_id) ;
187- }
188-
189- let mut builder =
190- TypeBuilder :: new ( self . tcx , def_id) . for_function_template ( & mut self . ctx , sig) ;
191- if let Some ( AnnotFormula :: Formula ( require) ) = require_annot {
192- let formula = require. map_var ( |idx| {
193- if idx. index ( ) == sig. inputs ( ) . len ( ) - 1 {
194- rty:: RefinedTypeVar :: Value
195- } else {
196- rty:: RefinedTypeVar :: Free ( idx)
197- }
198- } ) ;
199- builder. param_refinement ( formula. into ( ) ) ;
200- }
201- if let Some ( AnnotFormula :: Formula ( ensure) ) = ensure_annot {
202- builder. ret_refinement ( ensure. into ( ) ) ;
203- }
204- for ( ident, annot_rty) in param_annots {
205- use annot:: Resolver as _;
206- let ( idx, _) = param_resolver. resolve ( ident) . expect ( "unknown param" ) ;
207- builder. param_rty ( idx, annot_rty) ;
208- }
209- if let Some ( ret_rty) = ret_annot {
210- builder. ret_rty ( ret_rty) ;
211- }
212-
213- // can't generate template with type parameter...
51+ . fn_sig ( local_def_id)
52+ . instantiate_identity ( )
53+ . skip_binder ( ) ;
21454 use mir_ty:: TypeVisitableExt as _;
215- if builder . would_contain_template ( ) && sig . has_param ( ) {
216- None
55+ if sig . has_param ( ) && !analyzer . is_fully_annotated ( ) {
56+ self . ctx . register_deferred_def ( local_def_id . to_def_id ( ) ) ;
21757 } else {
218- Some ( rty:: RefinedType :: unrefined ( builder. build ( ) . into ( ) ) )
58+ let expected = analyzer. expected_ty ( ) ;
59+ self . ctx . register_def ( local_def_id. to_def_id ( ) , expected) ;
21960 }
22061 }
22162
0 commit comments