@@ -97,6 +97,38 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
9797 // Syntactically, we are allowed to define the concrete type if:
9898 hir_id == scope
9999 }
100+
101+ fn collect_body_and_predicate_taits ( & mut self ) {
102+ // Look at all where bounds.
103+ self . tcx . predicates_of ( self . item ) . instantiate_identity ( self . tcx ) . visit_with ( self ) ;
104+ // An item is allowed to constrain opaques declared within its own body (but not nested within
105+ // nested functions).
106+ for id in self . find_taits_declared_in_body ( ) {
107+ self . opaques . extend ( self . tcx . opaque_types_defined_by ( id) )
108+ }
109+ }
110+
111+ #[ instrument( level = "trace" , skip( self ) , ret) ]
112+ fn find_taits_declared_in_body ( & self ) -> Vec < LocalDefId > {
113+ let body = self . tcx . hir ( ) . body ( self . tcx . hir ( ) . body_owned_by ( self . item ) ) . value ;
114+ struct TaitInBodyFinder < ' tcx > {
115+ /// Ids of type aliases found in the body
116+ type_aliases : Vec < LocalDefId > ,
117+ tcx : TyCtxt < ' tcx > ,
118+ }
119+ impl < ' v > intravisit:: Visitor < ' v > for TaitInBodyFinder < ' _ > {
120+ #[ instrument( level = "trace" , skip( self ) ) ]
121+ fn visit_nested_item ( & mut self , id : rustc_hir:: ItemId ) {
122+ let id = id. owner_id . def_id ;
123+ if let DefKind :: TyAlias = self . tcx . def_kind ( id) {
124+ self . type_aliases . push ( id) ;
125+ }
126+ }
127+ }
128+ let mut visitor = TaitInBodyFinder { type_aliases : Default :: default ( ) , tcx : self . tcx } ;
129+ visitor. visit_expr ( body) ;
130+ visitor. type_aliases
131+ }
100132}
101133
102134impl < ' tcx > TypeVisitor < TyCtxt < ' tcx > > for OpaqueTypeCollector < ' tcx > {
@@ -274,13 +306,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
274306 }
275307 _ => unreachable ! ( ) ,
276308 }
277- // Look at all where bounds.
278- tcx. predicates_of ( item) . instantiate_identity ( tcx) . visit_with ( & mut collector) ;
279- // An item is allowed to constrain opaques declared within its own body (but not nested within
280- // nested functions).
281- for id in find_taits_declared_in_body ( tcx, item) {
282- collector. opaques . extend ( tcx. opaque_types_defined_by ( id) )
283- }
309+ collector. collect_body_and_predicate_taits ( ) ;
284310 }
285311 DefKind :: TyAlias | DefKind :: AssocTy => {
286312 tcx. type_of ( item) . subst_identity ( ) . visit_with ( & mut collector) ;
@@ -317,28 +343,6 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
317343 tcx. arena . alloc_from_iter ( collector. opaques )
318344}
319345
320- #[ instrument( level = "trace" , skip( tcx) , ret) ]
321- fn find_taits_declared_in_body ( tcx : TyCtxt < ' _ > , item : LocalDefId ) -> Vec < LocalDefId > {
322- let body = tcx. hir ( ) . body ( tcx. hir ( ) . body_owned_by ( item) ) . value ;
323- struct TaitInBodyFinder < ' tcx > {
324- /// Ids of type aliases found in the body
325- type_aliases : Vec < LocalDefId > ,
326- tcx : TyCtxt < ' tcx > ,
327- }
328- impl < ' v > intravisit:: Visitor < ' v > for TaitInBodyFinder < ' _ > {
329- #[ instrument( level = "trace" , skip( self ) ) ]
330- fn visit_nested_item ( & mut self , id : rustc_hir:: ItemId ) {
331- let id = id. owner_id . def_id ;
332- if let DefKind :: TyAlias = self . tcx . def_kind ( id) {
333- self . type_aliases . push ( id) ;
334- }
335- }
336- }
337- let mut visitor = TaitInBodyFinder { type_aliases : Default :: default ( ) , tcx } ;
338- visitor. visit_expr ( body) ;
339- visitor. type_aliases
340- }
341-
342346pub ( super ) fn provide ( providers : & mut Providers ) {
343347 * providers = Providers { opaque_types_defined_by, ..* providers } ;
344348}
0 commit comments