|
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