|
51 | 51 |
|
52 | 52 |
|
53 | 53 | use middle::const_eval; |
| 54 | +use middle::lint; |
54 | 55 | use middle::ty::{substs}; |
55 | 56 | use middle::ty::{ty_param_substs_and_ty}; |
56 | 57 | use middle::ty; |
@@ -195,21 +196,43 @@ fn ast_path_substs<AC:AstConv,RS:RegionScope>( |
195 | 196 | }; |
196 | 197 |
|
197 | 198 | // Convert the type parameters supplied by the user. |
198 | | - let supplied_type_parameter_count = |
199 | | - path.segments.iter().flat_map(|s| s.types.iter()).len(); |
200 | | - if decl_generics.type_param_defs.len() != supplied_type_parameter_count { |
201 | | - this.tcx().sess.span_fatal( |
202 | | - path.span, |
203 | | - format!("wrong number of type arguments: expected {} but found {}", |
204 | | - decl_generics.type_param_defs.len(), |
205 | | - supplied_type_parameter_count)); |
| 199 | + let supplied_ty_param_count = path.segments.iter().flat_map(|s| s.types.iter()).len(); |
| 200 | + let formal_ty_param_count = decl_generics.type_param_defs.len(); |
| 201 | + let required_ty_param_count = decl_generics.type_param_defs.iter() |
| 202 | + .take_while(|x| x.default.is_none()) |
| 203 | + .len(); |
| 204 | + if supplied_ty_param_count < required_ty_param_count { |
| 205 | + let expected = if required_ty_param_count < formal_ty_param_count { |
| 206 | + "expected at least" |
| 207 | + } else { |
| 208 | + "expected" |
| 209 | + }; |
| 210 | + this.tcx().sess.span_fatal(path.span, |
| 211 | + format!("wrong number of type arguments: {} {} but found {}", |
| 212 | + expected, required_ty_param_count, supplied_ty_param_count)); |
| 213 | + } else if supplied_ty_param_count > formal_ty_param_count { |
| 214 | + let expected = if required_ty_param_count < formal_ty_param_count { |
| 215 | + "expected at most" |
| 216 | + } else { |
| 217 | + "expected" |
| 218 | + }; |
| 219 | + this.tcx().sess.span_fatal(path.span, |
| 220 | + format!("wrong number of type arguments: {} {} but found {}", |
| 221 | + expected, formal_ty_param_count, supplied_ty_param_count)); |
| 222 | + } |
| 223 | + |
| 224 | + if supplied_ty_param_count > required_ty_param_count { |
| 225 | + let id = path.segments.iter().flat_map(|s| s.types.iter()) |
| 226 | + .nth(required_ty_param_count).unwrap().id; |
| 227 | + this.tcx().sess.add_lint(lint::DefaultTypeParamUsage, id, path.span, |
| 228 | + ~"provided type arguments with defaults"); |
206 | 229 | } |
207 | | - let tps = path.segments |
208 | | - .iter() |
209 | | - .flat_map(|s| s.types.iter()) |
210 | | - .map(|&a_t| ast_ty_to_ty(this, rscope, a_t)) |
211 | | - .collect(); |
212 | 230 |
|
| 231 | + let defaults = decl_generics.type_param_defs.slice_from(supplied_ty_param_count) |
| 232 | + .iter().map(|&x| x.default.unwrap()); |
| 233 | + let tps = path.segments.iter().flat_map(|s| s.types.iter()) |
| 234 | + .map(|&a_t| ast_ty_to_ty(this, rscope, a_t)) |
| 235 | + .chain(defaults).collect(); |
213 | 236 | substs { |
214 | 237 | regions: ty::NonerasedRegions(regions), |
215 | 238 | self_ty: self_ty, |
|
0 commit comments