|
1 |
| -use super::{InferCtxt, FixupError, FixupResult}; |
| 1 | +use super::{InferCtxt, FixupError, FixupResult, Span, type_variable::TypeVariableOrigin}; |
2 | 2 | use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
|
3 | 3 | use crate::ty::fold::{TypeFolder, TypeVisitor};
|
4 | 4 |
|
@@ -77,40 +77,58 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeAndRegionResolv
|
77 | 77 | ///////////////////////////////////////////////////////////////////////////
|
78 | 78 | // UNRESOLVED TYPE FINDER
|
79 | 79 |
|
80 |
| -/// The unresolved type **finder** walks your type and searches for |
81 |
| -/// type variables that don't yet have a value. They get pushed into a |
82 |
| -/// vector. It does not construct the fully resolved type (which might |
| 80 | +/// The unresolved type **finder** walks a type searching for |
| 81 | +/// type variables that don't yet have a value. The first unresolved type is stored. |
| 82 | +/// It does not construct the fully resolved type (which might |
83 | 83 | /// involve some hashing and so forth).
|
84 | 84 | pub struct UnresolvedTypeFinder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
85 | 85 | infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
| 86 | + |
| 87 | + /// Used to find the type parameter name and location for error reporting. |
| 88 | + pub first_unresolved: Option<(Ty<'tcx>,Option<Span>)>, |
86 | 89 | }
|
87 | 90 |
|
88 | 91 | impl<'a, 'gcx, 'tcx> UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
|
89 | 92 | pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
|
90 |
| - UnresolvedTypeFinder { infcx } |
| 93 | + UnresolvedTypeFinder { infcx, first_unresolved: None } |
91 | 94 | }
|
92 | 95 | }
|
93 | 96 |
|
94 | 97 | impl<'a, 'gcx, 'tcx> TypeVisitor<'tcx> for UnresolvedTypeFinder<'a, 'gcx, 'tcx> {
|
95 | 98 | fn visit_ty(&mut self, t: Ty<'tcx>) -> bool {
|
96 | 99 | let t = self.infcx.shallow_resolve(t);
|
97 | 100 | if t.has_infer_types() {
|
98 |
| - if let ty::Infer(_) = t.sty { |
| 101 | + if let ty::Infer(infer_ty) = t.sty { |
99 | 102 | // Since we called `shallow_resolve` above, this must
|
100 | 103 | // be an (as yet...) unresolved inference variable.
|
101 |
| - true |
| 104 | + let ty_var_span = |
| 105 | + if let ty::TyVar(ty_vid) = infer_ty { |
| 106 | + let ty_vars = self.infcx.type_variables.borrow(); |
| 107 | + if let TypeVariableOrigin::TypeParameterDefinition(span, _name) |
| 108 | + = *ty_vars.var_origin(ty_vid) |
| 109 | + { |
| 110 | + Some(span) |
| 111 | + } else { |
| 112 | + None |
| 113 | + } |
| 114 | + } else { |
| 115 | + None |
| 116 | + }; |
| 117 | + self.first_unresolved = Some((t, ty_var_span)); |
| 118 | + true // Halt visiting. |
102 | 119 | } else {
|
103 | 120 | // Otherwise, visit its contents.
|
104 | 121 | t.super_visit_with(self)
|
105 | 122 | }
|
106 | 123 | } else {
|
107 |
| - // Micro-optimize: no inference types at all Can't have unresolved type |
108 |
| - // variables, no need to visit the contents. |
| 124 | + // All type variables in inference types must already be resolved, |
| 125 | + // - no need to visit the contents, continue visiting. |
109 | 126 | false
|
110 | 127 | }
|
111 | 128 | }
|
112 | 129 | }
|
113 | 130 |
|
| 131 | + |
114 | 132 | ///////////////////////////////////////////////////////////////////////////
|
115 | 133 | // FULL TYPE RESOLUTION
|
116 | 134 |
|
|
0 commit comments