|
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