|
1 | 1 | use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
2 | 2 | use super::{FixupError, FixupResult, InferCtxt, Span};
|
| 3 | +use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind}; |
3 | 4 | use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFolder, TypeSuperFoldable};
|
4 | 5 | use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitor};
|
5 | 6 | use rustc_middle::ty::{self, Const, InferConst, Ty, TyCtxt, TypeFoldable, TypeVisitable};
|
@@ -110,48 +111,77 @@ impl<'a, 'tcx> TypeFolder<'tcx> for OpportunisticRegionResolver<'a, 'tcx> {
|
110 | 111 | /// type variables that don't yet have a value. The first unresolved type is stored.
|
111 | 112 | /// It does not construct the fully resolved type (which might
|
112 | 113 | /// involve some hashing and so forth).
|
113 |
| -pub struct UnresolvedTypeFinder<'a, 'tcx> { |
| 114 | +pub struct UnresolvedTypeOrConstFinder<'a, 'tcx> { |
114 | 115 | infcx: &'a InferCtxt<'tcx>,
|
115 | 116 | }
|
116 | 117 |
|
117 |
| -impl<'a, 'tcx> UnresolvedTypeFinder<'a, 'tcx> { |
| 118 | +impl<'a, 'tcx> UnresolvedTypeOrConstFinder<'a, 'tcx> { |
118 | 119 | pub fn new(infcx: &'a InferCtxt<'tcx>) -> Self {
|
119 |
| - UnresolvedTypeFinder { infcx } |
| 120 | + UnresolvedTypeOrConstFinder { infcx } |
120 | 121 | }
|
121 | 122 | }
|
122 | 123 |
|
123 |
| -impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'tcx> { |
124 |
| - type BreakTy = (Ty<'tcx>, Option<Span>); |
| 124 | +impl<'a, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeOrConstFinder<'a, 'tcx> { |
| 125 | + type BreakTy = (ty::Term<'tcx>, Option<Span>); |
125 | 126 | fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
|
126 | 127 | let t = self.infcx.shallow_resolve(t);
|
127 |
| - if t.has_infer_types() { |
128 |
| - if let ty::Infer(infer_ty) = *t.kind() { |
129 |
| - // Since we called `shallow_resolve` above, this must |
130 |
| - // be an (as yet...) unresolved inference variable. |
131 |
| - let ty_var_span = if let ty::TyVar(ty_vid) = infer_ty { |
132 |
| - let mut inner = self.infcx.inner.borrow_mut(); |
133 |
| - let ty_vars = &inner.type_variables(); |
134 |
| - if let TypeVariableOrigin { |
135 |
| - kind: TypeVariableOriginKind::TypeParameterDefinition(_, _), |
136 |
| - span, |
137 |
| - } = *ty_vars.var_origin(ty_vid) |
138 |
| - { |
139 |
| - Some(span) |
140 |
| - } else { |
141 |
| - None |
142 |
| - } |
| 128 | + if let ty::Infer(infer_ty) = *t.kind() { |
| 129 | + // Since we called `shallow_resolve` above, this must |
| 130 | + // be an (as yet...) unresolved inference variable. |
| 131 | + let ty_var_span = if let ty::TyVar(ty_vid) = infer_ty { |
| 132 | + let mut inner = self.infcx.inner.borrow_mut(); |
| 133 | + let ty_vars = &inner.type_variables(); |
| 134 | + if let TypeVariableOrigin { |
| 135 | + kind: TypeVariableOriginKind::TypeParameterDefinition(_, _), |
| 136 | + span, |
| 137 | + } = *ty_vars.var_origin(ty_vid) |
| 138 | + { |
| 139 | + Some(span) |
143 | 140 | } else {
|
144 | 141 | None
|
145 |
| - }; |
146 |
| - ControlFlow::Break((t, ty_var_span)) |
| 142 | + } |
147 | 143 | } else {
|
148 |
| - // Otherwise, visit its contents. |
149 |
| - t.super_visit_with(self) |
150 |
| - } |
| 144 | + None |
| 145 | + }; |
| 146 | + ControlFlow::Break((t.into(), ty_var_span)) |
| 147 | + } else if !t.has_non_region_infer() { |
| 148 | + // All const/type variables in inference types must already be resolved, |
| 149 | + // no need to visit the contents. |
| 150 | + ControlFlow::CONTINUE |
151 | 151 | } else {
|
152 |
| - // All type variables in inference types must already be resolved, |
153 |
| - // - no need to visit the contents, continue visiting. |
| 152 | + // Otherwise, keep visiting. |
| 153 | + t.super_visit_with(self) |
| 154 | + } |
| 155 | + } |
| 156 | + |
| 157 | + fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> { |
| 158 | + let ct = self.infcx.shallow_resolve(ct); |
| 159 | + if let ty::ConstKind::Infer(i) = ct.kind() { |
| 160 | + // Since we called `shallow_resolve` above, this must |
| 161 | + // be an (as yet...) unresolved inference variable. |
| 162 | + let ct_var_span = if let ty::InferConst::Var(vid) = i { |
| 163 | + let mut inner = self.infcx.inner.borrow_mut(); |
| 164 | + let ct_vars = &mut inner.const_unification_table(); |
| 165 | + if let ConstVariableOrigin { |
| 166 | + span, |
| 167 | + kind: ConstVariableOriginKind::ConstParameterDefinition(_, _), |
| 168 | + } = ct_vars.probe_value(vid).origin |
| 169 | + { |
| 170 | + Some(span) |
| 171 | + } else { |
| 172 | + None |
| 173 | + } |
| 174 | + } else { |
| 175 | + None |
| 176 | + }; |
| 177 | + ControlFlow::Break((ct.into(), ct_var_span)) |
| 178 | + } else if !ct.has_non_region_infer() { |
| 179 | + // All const/type variables in inference types must already be resolved, |
| 180 | + // no need to visit the contents. |
154 | 181 | ControlFlow::CONTINUE
|
| 182 | + } else { |
| 183 | + // Otherwise, keep visiting. |
| 184 | + ct.super_visit_with(self) |
155 | 185 | }
|
156 | 186 | }
|
157 | 187 | }
|
|
0 commit comments