3939//! - u.visit_with(visitor)
4040//! ```
4141use crate :: ty:: { self , flags:: FlagComputation , Binder , Ty , TyCtxt , TypeFlags } ;
42+ use rustc_errors:: ErrorGuaranteed ;
4243
4344use rustc_data_structures:: fx:: FxHashSet ;
4445use rustc_data_structures:: sso:: SsoHashSet ;
4546use std:: ops:: ControlFlow ;
4647
47- pub trait TypeVisitable < ' tcx > = ir:: TypeVisitable < ' tcx > + ir :: TypeVisitableExt <' tcx > ;
48+ pub trait TypeVisitable < ' tcx > = ir:: TypeVisitable < ' tcx > + TypeVisitableExt <' tcx > ;
4849pub trait TypeSuperVisitable < ' tcx > = ir:: TypeSuperVisitable < ' tcx > ;
4950pub trait TypeVisitor < ' tcx > = ir:: TypeVisitor < ' tcx > ;
5051
5152pub mod ir {
52- use crate :: ty:: { self , Binder , Ty , TypeFlags } ;
53- use rustc_errors:: ErrorGuaranteed ;
53+ use crate :: ty:: { self , Binder , Ty } ;
5454
5555 use std:: fmt;
5656 use std:: ops:: ControlFlow ;
5757
58- use super :: { FoundFlags , HasEscapingVarsVisitor , HasTypeFlagsVisitor } ;
59-
6058 /// This trait is implemented for every type that can be visited,
6159 /// providing the skeleton of the traversal.
6260 ///
@@ -76,131 +74,6 @@ pub mod ir {
7674 fn visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> ControlFlow < V :: BreakTy > ;
7775 }
7876
79- pub trait TypeVisitableExt < ' tcx > : TypeVisitable < ' tcx > {
80- /// Returns `true` if `self` has any late-bound regions that are either
81- /// bound by `binder` or bound by some binder outside of `binder`.
82- /// If `binder` is `ty::INNERMOST`, this indicates whether
83- /// there are any late-bound regions that appear free.
84- fn has_vars_bound_at_or_above ( & self , binder : ty:: DebruijnIndex ) -> bool {
85- self . visit_with ( & mut HasEscapingVarsVisitor { outer_index : binder } ) . is_break ( )
86- }
87-
88- /// Returns `true` if this type has any regions that escape `binder` (and
89- /// hence are not bound by it).
90- fn has_vars_bound_above ( & self , binder : ty:: DebruijnIndex ) -> bool {
91- self . has_vars_bound_at_or_above ( binder. shifted_in ( 1 ) )
92- }
93-
94- /// Return `true` if this type has regions that are not a part of the type.
95- /// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
96- /// would return `true`. The latter can occur when traversing through the
97- /// former.
98- ///
99- /// See [`HasEscapingVarsVisitor`] for more information.
100- fn has_escaping_bound_vars ( & self ) -> bool {
101- self . has_vars_bound_at_or_above ( ty:: INNERMOST )
102- }
103-
104- fn has_type_flags ( & self , flags : TypeFlags ) -> bool {
105- let res = self . visit_with ( & mut HasTypeFlagsVisitor { flags } ) . break_value ( )
106- == Some ( FoundFlags ) ;
107- trace ! ( ?self , ?flags, ?res, "has_type_flags" ) ;
108- res
109- }
110- fn has_projections ( & self ) -> bool {
111- self . has_type_flags ( TypeFlags :: HAS_PROJECTION )
112- }
113- fn has_opaque_types ( & self ) -> bool {
114- self . has_type_flags ( TypeFlags :: HAS_TY_OPAQUE )
115- }
116- fn has_generators ( & self ) -> bool {
117- self . has_type_flags ( TypeFlags :: HAS_TY_GENERATOR )
118- }
119- fn references_error ( & self ) -> bool {
120- self . has_type_flags ( TypeFlags :: HAS_ERROR )
121- }
122- fn error_reported ( & self ) -> Result < ( ) , ErrorGuaranteed > {
123- if self . references_error ( ) {
124- if let Some ( reported) = ty:: tls:: with ( |tcx| tcx. sess . is_compilation_going_to_fail ( ) )
125- {
126- Err ( reported)
127- } else {
128- bug ! ( "expect tcx.sess.is_compilation_going_to_fail return `Some`" ) ;
129- }
130- } else {
131- Ok ( ( ) )
132- }
133- }
134- fn has_non_region_param ( & self ) -> bool {
135- self . has_type_flags ( TypeFlags :: NEEDS_SUBST - TypeFlags :: HAS_RE_PARAM )
136- }
137- fn has_infer_regions ( & self ) -> bool {
138- self . has_type_flags ( TypeFlags :: HAS_RE_INFER )
139- }
140- fn has_infer_types ( & self ) -> bool {
141- self . has_type_flags ( TypeFlags :: HAS_TY_INFER )
142- }
143- fn has_non_region_infer ( & self ) -> bool {
144- self . has_type_flags ( TypeFlags :: NEEDS_INFER - TypeFlags :: HAS_RE_INFER )
145- }
146- fn needs_infer ( & self ) -> bool {
147- self . has_type_flags ( TypeFlags :: NEEDS_INFER )
148- }
149- fn has_placeholders ( & self ) -> bool {
150- self . has_type_flags (
151- TypeFlags :: HAS_RE_PLACEHOLDER
152- | TypeFlags :: HAS_TY_PLACEHOLDER
153- | TypeFlags :: HAS_CT_PLACEHOLDER ,
154- )
155- }
156- fn needs_subst ( & self ) -> bool {
157- self . has_type_flags ( TypeFlags :: NEEDS_SUBST )
158- }
159- /// "Free" regions in this context means that it has any region
160- /// that is not (a) erased or (b) late-bound.
161- fn has_free_regions ( & self ) -> bool {
162- self . has_type_flags ( TypeFlags :: HAS_FREE_REGIONS )
163- }
164-
165- fn has_erased_regions ( & self ) -> bool {
166- self . has_type_flags ( TypeFlags :: HAS_RE_ERASED )
167- }
168-
169- /// True if there are any un-erased free regions.
170- fn has_erasable_regions ( & self ) -> bool {
171- self . has_type_flags ( TypeFlags :: HAS_FREE_REGIONS )
172- }
173-
174- /// Indicates whether this value references only 'global'
175- /// generic parameters that are the same regardless of what fn we are
176- /// in. This is used for caching.
177- fn is_global ( & self ) -> bool {
178- !self . has_type_flags ( TypeFlags :: HAS_FREE_LOCAL_NAMES )
179- }
180-
181- /// True if there are any late-bound regions
182- fn has_late_bound_regions ( & self ) -> bool {
183- self . has_type_flags ( TypeFlags :: HAS_RE_LATE_BOUND )
184- }
185- /// True if there are any late-bound non-region variables
186- fn has_non_region_late_bound ( & self ) -> bool {
187- self . has_type_flags ( TypeFlags :: HAS_LATE_BOUND - TypeFlags :: HAS_RE_LATE_BOUND )
188- }
189- /// True if there are any late-bound variables
190- fn has_late_bound_vars ( & self ) -> bool {
191- self . has_type_flags ( TypeFlags :: HAS_LATE_BOUND )
192- }
193-
194- /// Indicates whether this value still has parameters/placeholders/inference variables
195- /// which could be replaced later, in a way that would change the results of `impl`
196- /// specialization.
197- fn still_further_specializable ( & self ) -> bool {
198- self . has_type_flags ( TypeFlags :: STILL_FURTHER_SPECIALIZABLE )
199- }
200- }
201-
202- impl < ' tcx , T : TypeVisitable < ' tcx > > TypeVisitableExt < ' tcx > for T { }
203-
20477 pub trait TypeSuperVisitable < ' tcx > : TypeVisitable < ' tcx > {
20578 /// Provides a default visit for a type of interest. This should only be
20679 /// called within `TypeVisitor` methods, when a non-custom traversal is
@@ -245,6 +118,130 @@ pub mod ir {
245118 }
246119}
247120
121+ pub trait TypeVisitableExt < ' tcx > : ir:: TypeVisitable < ' tcx > {
122+ /// Returns `true` if `self` has any late-bound regions that are either
123+ /// bound by `binder` or bound by some binder outside of `binder`.
124+ /// If `binder` is `ty::INNERMOST`, this indicates whether
125+ /// there are any late-bound regions that appear free.
126+ fn has_vars_bound_at_or_above ( & self , binder : ty:: DebruijnIndex ) -> bool {
127+ self . visit_with ( & mut HasEscapingVarsVisitor { outer_index : binder } ) . is_break ( )
128+ }
129+
130+ /// Returns `true` if this type has any regions that escape `binder` (and
131+ /// hence are not bound by it).
132+ fn has_vars_bound_above ( & self , binder : ty:: DebruijnIndex ) -> bool {
133+ self . has_vars_bound_at_or_above ( binder. shifted_in ( 1 ) )
134+ }
135+
136+ /// Return `true` if this type has regions that are not a part of the type.
137+ /// For example, `for<'a> fn(&'a i32)` return `false`, while `fn(&'a i32)`
138+ /// would return `true`. The latter can occur when traversing through the
139+ /// former.
140+ ///
141+ /// See [`HasEscapingVarsVisitor`] for more information.
142+ fn has_escaping_bound_vars ( & self ) -> bool {
143+ self . has_vars_bound_at_or_above ( ty:: INNERMOST )
144+ }
145+
146+ fn has_type_flags ( & self , flags : TypeFlags ) -> bool {
147+ let res =
148+ self . visit_with ( & mut HasTypeFlagsVisitor { flags } ) . break_value ( ) == Some ( FoundFlags ) ;
149+ trace ! ( ?self , ?flags, ?res, "has_type_flags" ) ;
150+ res
151+ }
152+ fn has_projections ( & self ) -> bool {
153+ self . has_type_flags ( TypeFlags :: HAS_PROJECTION )
154+ }
155+ fn has_opaque_types ( & self ) -> bool {
156+ self . has_type_flags ( TypeFlags :: HAS_TY_OPAQUE )
157+ }
158+ fn has_generators ( & self ) -> bool {
159+ self . has_type_flags ( TypeFlags :: HAS_TY_GENERATOR )
160+ }
161+ fn references_error ( & self ) -> bool {
162+ self . has_type_flags ( TypeFlags :: HAS_ERROR )
163+ }
164+ fn error_reported ( & self ) -> Result < ( ) , ErrorGuaranteed > {
165+ if self . references_error ( ) {
166+ if let Some ( reported) = ty:: tls:: with ( |tcx| tcx. sess . is_compilation_going_to_fail ( ) ) {
167+ Err ( reported)
168+ } else {
169+ bug ! ( "expect tcx.sess.is_compilation_going_to_fail return `Some`" ) ;
170+ }
171+ } else {
172+ Ok ( ( ) )
173+ }
174+ }
175+ fn has_non_region_param ( & self ) -> bool {
176+ self . has_type_flags ( TypeFlags :: NEEDS_SUBST - TypeFlags :: HAS_RE_PARAM )
177+ }
178+ fn has_infer_regions ( & self ) -> bool {
179+ self . has_type_flags ( TypeFlags :: HAS_RE_INFER )
180+ }
181+ fn has_infer_types ( & self ) -> bool {
182+ self . has_type_flags ( TypeFlags :: HAS_TY_INFER )
183+ }
184+ fn has_non_region_infer ( & self ) -> bool {
185+ self . has_type_flags ( TypeFlags :: NEEDS_INFER - TypeFlags :: HAS_RE_INFER )
186+ }
187+ fn needs_infer ( & self ) -> bool {
188+ self . has_type_flags ( TypeFlags :: NEEDS_INFER )
189+ }
190+ fn has_placeholders ( & self ) -> bool {
191+ self . has_type_flags (
192+ TypeFlags :: HAS_RE_PLACEHOLDER
193+ | TypeFlags :: HAS_TY_PLACEHOLDER
194+ | TypeFlags :: HAS_CT_PLACEHOLDER ,
195+ )
196+ }
197+ fn needs_subst ( & self ) -> bool {
198+ self . has_type_flags ( TypeFlags :: NEEDS_SUBST )
199+ }
200+ /// "Free" regions in this context means that it has any region
201+ /// that is not (a) erased or (b) late-bound.
202+ fn has_free_regions ( & self ) -> bool {
203+ self . has_type_flags ( TypeFlags :: HAS_FREE_REGIONS )
204+ }
205+
206+ fn has_erased_regions ( & self ) -> bool {
207+ self . has_type_flags ( TypeFlags :: HAS_RE_ERASED )
208+ }
209+
210+ /// True if there are any un-erased free regions.
211+ fn has_erasable_regions ( & self ) -> bool {
212+ self . has_type_flags ( TypeFlags :: HAS_FREE_REGIONS )
213+ }
214+
215+ /// Indicates whether this value references only 'global'
216+ /// generic parameters that are the same regardless of what fn we are
217+ /// in. This is used for caching.
218+ fn is_global ( & self ) -> bool {
219+ !self . has_type_flags ( TypeFlags :: HAS_FREE_LOCAL_NAMES )
220+ }
221+
222+ /// True if there are any late-bound regions
223+ fn has_late_bound_regions ( & self ) -> bool {
224+ self . has_type_flags ( TypeFlags :: HAS_RE_LATE_BOUND )
225+ }
226+ /// True if there are any late-bound non-region variables
227+ fn has_non_region_late_bound ( & self ) -> bool {
228+ self . has_type_flags ( TypeFlags :: HAS_LATE_BOUND - TypeFlags :: HAS_RE_LATE_BOUND )
229+ }
230+ /// True if there are any late-bound variables
231+ fn has_late_bound_vars ( & self ) -> bool {
232+ self . has_type_flags ( TypeFlags :: HAS_LATE_BOUND )
233+ }
234+
235+ /// Indicates whether this value still has parameters/placeholders/inference variables
236+ /// which could be replaced later, in a way that would change the results of `impl`
237+ /// specialization.
238+ fn still_further_specializable ( & self ) -> bool {
239+ self . has_type_flags ( TypeFlags :: STILL_FURTHER_SPECIALIZABLE )
240+ }
241+ }
242+
243+ impl < ' tcx , T : ir:: TypeVisitable < ' tcx > > TypeVisitableExt < ' tcx > for T { }
244+
248245///////////////////////////////////////////////////////////////////////////
249246// Region folder
250247
0 commit comments