13
13
use middle:: ty;
14
14
use middle:: ty_fold;
15
15
use middle:: ty_fold:: TypeFolder ;
16
+ use util:: ppaux:: Repr ;
16
17
17
18
use std:: rc:: Rc ;
19
+ use syntax:: codemap:: Span ;
18
20
use syntax:: opt_vec:: OptVec ;
19
21
20
22
///////////////////////////////////////////////////////////////////////////
21
23
// Public trait `Subst`
22
24
//
23
25
// Just call `foo.subst(tcx, substs)` to perform a substitution across
24
26
// `foo`.
27
+ // Or use `foo.subst_spanned(tcx, substs, Some(span))` when there is more
28
+ // information available (for better errors).
25
29
26
30
pub trait Subst {
27
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> Self ;
31
+ fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> Self {
32
+ self . subst_spanned ( tcx, substs, None )
33
+ }
34
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
35
+ substs : & ty:: substs ,
36
+ span : Option < Span > ) -> Self ;
28
37
}
29
38
30
39
///////////////////////////////////////////////////////////////////////////
@@ -36,19 +45,32 @@ pub trait Subst {
36
45
// our current method/trait matching algorithm. - Niko
37
46
38
47
impl Subst for ty:: t {
39
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: t {
40
- if ty:: substs_is_noop ( substs) {
48
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
49
+ substs : & ty:: substs ,
50
+ span : Option < Span > ) -> ty:: t {
51
+ if ty:: substs_is_noop ( substs) && !ty:: type_has_params ( * self ) {
41
52
* self
42
53
} else {
43
- let mut folder = SubstFolder { tcx : tcx, substs : substs} ;
54
+ let mut folder = SubstFolder {
55
+ tcx : tcx,
56
+ substs : substs,
57
+ span : span,
58
+ root_ty : Some ( * self )
59
+ } ;
44
60
folder. fold_ty ( * self )
45
61
}
46
62
}
47
63
}
48
64
49
65
struct SubstFolder < ' a > {
50
66
tcx : ty:: ctxt ,
51
- substs : & ' a ty:: substs
67
+ substs : & ' a ty:: substs ,
68
+
69
+ // The location for which the substitution is performed, if available.
70
+ span : Option < Span > ,
71
+
72
+ // The root type that is being substituted, if available.
73
+ root_ty : Option < ty:: t >
52
74
}
53
75
54
76
impl < ' a > TypeFolder for SubstFolder < ' a > {
@@ -65,14 +87,42 @@ impl<'a> TypeFolder for SubstFolder<'a> {
65
87
66
88
match ty:: get ( t) . sty {
67
89
ty:: ty_param( p) => {
68
- self . substs . tps [ p. idx ]
90
+ if p. idx < self . substs . tps . len ( ) {
91
+ self . substs . tps [ p. idx ]
92
+ } else {
93
+ let root_msg = match self . root_ty {
94
+ Some ( root) => format ! ( " in the substitution of `{}`" ,
95
+ root. repr( self . tcx) ) ,
96
+ None => ~""
97
+ } ;
98
+ let m = format ! ( "missing type param `{}`{}" ,
99
+ t. repr( self . tcx) , root_msg) ;
100
+ match self . span {
101
+ Some ( span) => self . tcx . sess . span_err ( span, m) ,
102
+ None => self . tcx . sess . err ( m)
103
+ }
104
+ ty:: mk_err( )
105
+ }
69
106
}
70
107
ty:: ty_self( _) => {
71
- self . substs . self_ty . expect ( "ty_self not found in substs" )
72
- }
73
- _ => {
74
- ty_fold:: super_fold_ty ( self , t)
108
+ match self . substs. self_ty {
109
+ Some ( ty) => ty,
110
+ None => {
111
+ let root_msg = match self . root_ty {
112
+ Some ( root) => format ! ( " in the substitution of `{}`" ,
113
+ root. repr( self . tcx) ) ,
114
+ None => ~""
115
+ } ;
116
+ let m = format ! ( "missing `Self` type param{}" , root_msg) ;
117
+ match self . span {
118
+ Some ( span) => self . tcx . sess . span_err ( span, m) ,
119
+ None => self . tcx . sess . err ( m)
120
+ }
121
+ ty:: mk_err( )
122
+ }
123
+ }
75
124
}
125
+ _ => ty_fold:: super_fold_ty ( self , t)
76
126
}
77
127
}
78
128
}
@@ -81,112 +131,145 @@ impl<'a> TypeFolder for SubstFolder<'a> {
81
131
// Other types
82
132
83
133
impl < T : Subst > Subst for ~[ T ] {
84
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ~[ T ] {
85
- self . map ( |t| t. subst ( tcx, substs) )
134
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
135
+ substs : & ty:: substs ,
136
+ span : Option < Span > ) -> ~[ T ] {
137
+ self . map ( |t| t. subst_spanned ( tcx, substs, span) )
86
138
}
87
139
}
88
140
impl < T : Subst > Subst for Rc < T > {
89
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> Rc < T > {
90
- Rc :: new ( self . borrow ( ) . subst ( tcx, substs) )
141
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
142
+ substs : & ty:: substs ,
143
+ span : Option < Span > ) -> Rc < T > {
144
+ Rc :: new ( self . borrow ( ) . subst_spanned ( tcx, substs, span) )
91
145
}
92
146
}
93
147
94
148
impl < T : Subst > Subst for OptVec < T > {
95
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> OptVec < T > {
96
- self . map ( |t| t. subst ( tcx, substs) )
149
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
150
+ substs : & ty:: substs ,
151
+ span : Option < Span > ) -> OptVec < T > {
152
+ self . map ( |t| t. subst_spanned ( tcx, substs, span) )
97
153
}
98
154
}
99
155
100
156
impl < T : Subst + ' static > Subst for @T {
101
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> @T {
157
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
158
+ substs : & ty:: substs ,
159
+ span : Option < Span > ) -> @T {
102
160
match self {
103
- t => @( * * t) . subst ( tcx, substs)
161
+ t => @( * * t) . subst_spanned ( tcx, substs, span )
104
162
}
105
163
}
106
164
}
107
165
108
166
impl < T : Subst > Subst for Option < T > {
109
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> Option < T > {
110
- self . as_ref ( ) . map ( |t| t. subst ( tcx, substs) )
167
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
168
+ substs : & ty:: substs ,
169
+ span : Option < Span > ) -> Option < T > {
170
+ self . as_ref ( ) . map ( |t| t. subst_spanned ( tcx, substs, span) )
111
171
}
112
172
}
113
173
114
174
impl Subst for ty:: TraitRef {
115
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: TraitRef {
175
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
176
+ substs : & ty:: substs ,
177
+ span : Option < Span > ) -> ty:: TraitRef {
116
178
ty:: TraitRef {
117
179
def_id : self . def_id ,
118
- substs : self . substs . subst ( tcx, substs)
180
+ substs : self . substs . subst_spanned ( tcx, substs, span )
119
181
}
120
182
}
121
183
}
122
184
123
185
impl Subst for ty:: substs {
124
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: substs {
186
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
187
+ substs : & ty:: substs ,
188
+ span : Option < Span > ) -> ty:: substs {
125
189
ty:: substs {
126
- regions : self . regions . subst ( tcx, substs) ,
127
- self_ty : self . self_ty . map ( |typ| typ. subst ( tcx, substs) ) ,
128
- tps : self . tps . map ( |typ| typ. subst ( tcx, substs) )
190
+ regions : self . regions . subst_spanned ( tcx, substs, span ) ,
191
+ self_ty : self . self_ty . map ( |typ| typ. subst_spanned ( tcx, substs, span ) ) ,
192
+ tps : self . tps . map ( |typ| typ. subst_spanned ( tcx, substs, span ) )
129
193
}
130
194
}
131
195
}
132
196
133
197
impl Subst for ty:: RegionSubsts {
134
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: RegionSubsts {
198
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
199
+ substs : & ty:: substs ,
200
+ span : Option < Span > ) -> ty:: RegionSubsts {
135
201
match * self {
136
202
ty:: ErasedRegions => {
137
203
ty:: ErasedRegions
138
204
}
139
205
ty:: NonerasedRegions ( ref regions) => {
140
- ty:: NonerasedRegions ( regions. subst ( tcx, substs) )
206
+ ty:: NonerasedRegions ( regions. subst_spanned ( tcx, substs, span ) )
141
207
}
142
208
}
143
209
}
144
210
}
145
211
146
212
impl Subst for ty:: BareFnTy {
147
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: BareFnTy {
148
- let mut folder = SubstFolder { tcx : tcx, substs : substs} ;
213
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
214
+ substs : & ty:: substs ,
215
+ span : Option < Span > ) -> ty:: BareFnTy {
216
+ let mut folder = SubstFolder {
217
+ tcx : tcx,
218
+ substs : substs,
219
+ span : span,
220
+ root_ty : None
221
+ } ;
149
222
folder. fold_bare_fn_ty ( self )
150
223
}
151
224
}
152
225
153
226
impl Subst for ty:: ParamBounds {
154
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: ParamBounds {
227
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
228
+ substs : & ty:: substs ,
229
+ span : Option < Span > ) -> ty:: ParamBounds {
155
230
ty:: ParamBounds {
156
231
builtin_bounds : self . builtin_bounds ,
157
- trait_bounds : self . trait_bounds . subst ( tcx, substs)
232
+ trait_bounds : self . trait_bounds . subst_spanned ( tcx, substs, span )
158
233
}
159
234
}
160
235
}
161
236
162
237
impl Subst for ty:: TypeParameterDef {
163
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: TypeParameterDef {
238
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
239
+ substs : & ty:: substs ,
240
+ span : Option < Span > ) -> ty:: TypeParameterDef {
164
241
ty:: TypeParameterDef {
165
242
ident : self . ident ,
166
243
def_id : self . def_id ,
167
- bounds : self . bounds . subst ( tcx, substs) ,
168
- default : self . default . map ( |x| x. subst ( tcx, substs) )
244
+ bounds : self . bounds . subst_spanned ( tcx, substs, span ) ,
245
+ default : self . default . map ( |x| x. subst_spanned ( tcx, substs, span ) )
169
246
}
170
247
}
171
248
}
172
249
173
250
impl Subst for ty:: Generics {
174
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: Generics {
251
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
252
+ substs : & ty:: substs ,
253
+ span : Option < Span > ) -> ty:: Generics {
175
254
ty:: Generics {
176
- type_param_defs : self . type_param_defs . subst ( tcx, substs) ,
177
- region_param_defs : self . region_param_defs . subst ( tcx, substs) ,
255
+ type_param_defs : self . type_param_defs . subst_spanned ( tcx, substs, span ) ,
256
+ region_param_defs : self . region_param_defs . subst_spanned ( tcx, substs, span ) ,
178
257
}
179
258
}
180
259
}
181
260
182
261
impl Subst for ty:: RegionParameterDef {
183
- fn subst ( & self , _: ty:: ctxt , _: & ty:: substs ) -> ty:: RegionParameterDef {
262
+ fn subst_spanned ( & self , _: ty:: ctxt ,
263
+ _: & ty:: substs ,
264
+ _: Option < Span > ) -> ty:: RegionParameterDef {
184
265
* self
185
266
}
186
267
}
187
268
188
269
impl Subst for ty:: Region {
189
- fn subst ( & self , _tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: Region {
270
+ fn subst_spanned ( & self , _tcx : ty:: ctxt ,
271
+ substs : & ty:: substs ,
272
+ _: Option < Span > ) -> ty:: Region {
190
273
// Note: This routine only handles regions that are bound on
191
274
// type declarationss and other outer declarations, not those
192
275
// bound in *fn types*. Region substitution of the bound
@@ -206,10 +289,12 @@ impl Subst for ty::Region {
206
289
}
207
290
208
291
impl Subst for ty:: ty_param_bounds_and_ty {
209
- fn subst ( & self , tcx : ty:: ctxt , substs : & ty:: substs ) -> ty:: ty_param_bounds_and_ty {
292
+ fn subst_spanned ( & self , tcx : ty:: ctxt ,
293
+ substs : & ty:: substs ,
294
+ span : Option < Span > ) -> ty:: ty_param_bounds_and_ty {
210
295
ty:: ty_param_bounds_and_ty {
211
- generics : self . generics . subst ( tcx, substs) ,
212
- ty : self . ty . subst ( tcx, substs)
296
+ generics : self . generics . subst_spanned ( tcx, substs, span ) ,
297
+ ty : self . ty . subst_spanned ( tcx, substs, span )
213
298
}
214
299
}
215
300
}
0 commit comments