39
39
//! - u.visit_with(visitor)
40
40
//! ```
41
41
use crate :: ty:: { self , flags:: FlagComputation , Binder , Ty , TyCtxt , TypeFlags } ;
42
+ use rustc_errors:: ErrorGuaranteed ;
42
43
43
44
use rustc_data_structures:: fx:: FxHashSet ;
44
45
use rustc_data_structures:: sso:: SsoHashSet ;
45
46
use std:: ops:: ControlFlow ;
46
47
47
- pub trait TypeVisitable < ' tcx > = ir:: TypeVisitable < ' tcx > + ir :: TypeVisitableExt <' tcx > ;
48
+ pub trait TypeVisitable < ' tcx > = ir:: TypeVisitable < ' tcx > + TypeVisitableExt <' tcx > ;
48
49
pub trait TypeSuperVisitable < ' tcx > = ir:: TypeSuperVisitable < ' tcx > ;
49
50
pub trait TypeVisitor < ' tcx > = ir:: TypeVisitor < ' tcx > ;
50
51
51
52
pub mod ir {
52
- use crate :: ty:: { self , Binder , Ty , TypeFlags } ;
53
- use rustc_errors:: ErrorGuaranteed ;
53
+ use crate :: ty:: { self , Binder , Ty } ;
54
54
55
55
use std:: fmt;
56
56
use std:: ops:: ControlFlow ;
57
57
58
- use super :: { FoundFlags , HasEscapingVarsVisitor , HasTypeFlagsVisitor } ;
59
-
60
58
/// This trait is implemented for every type that can be visited,
61
59
/// providing the skeleton of the traversal.
62
60
///
@@ -76,131 +74,6 @@ pub mod ir {
76
74
fn visit_with < V : TypeVisitor < ' tcx > > ( & self , visitor : & mut V ) -> ControlFlow < V :: BreakTy > ;
77
75
}
78
76
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
-
204
77
pub trait TypeSuperVisitable < ' tcx > : TypeVisitable < ' tcx > {
205
78
/// Provides a default visit for a type of interest. This should only be
206
79
/// called within `TypeVisitor` methods, when a non-custom traversal is
@@ -245,6 +118,130 @@ pub mod ir {
245
118
}
246
119
}
247
120
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
+
248
245
///////////////////////////////////////////////////////////////////////////
249
246
// Region folder
250
247
0 commit comments