|
10 | 10 |
|
11 | 11 | use super::{probe, MethodCallee};
|
12 | 12 |
|
| 13 | +use astconv::AstConv; |
13 | 14 | use check::{FnCtxt, LvalueOp, callee};
|
14 | 15 | use hir::def_id::DefId;
|
15 | 16 | use rustc::ty::subst::Substs;
|
@@ -282,60 +283,33 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
|
282 | 283 | segment: &hir::PathSegment,
|
283 | 284 | substs: &Substs<'tcx>)
|
284 | 285 | -> &'tcx Substs<'tcx> {
|
285 |
| - let supplied_method_types = match segment.parameters { |
286 |
| - hir::AngleBracketedParameters(ref data) => &data.types, |
287 |
| - _ => bug!("unexpected generic arguments: {:?}", segment.parameters), |
288 |
| - }; |
289 |
| - |
290 | 286 | // Determine the values for the generic parameters of the method.
|
291 | 287 | // If they were not explicitly supplied, just construct fresh
|
292 | 288 | // variables.
|
293 |
| - let num_supplied_types = supplied_method_types.len(); |
294 | 289 | let method_generics = self.tcx.generics_of(pick.item.def_id);
|
295 |
| - let num_method_types = method_generics.types.len(); |
296 |
| - |
297 |
| - if num_supplied_types > 0 && num_supplied_types != num_method_types { |
298 |
| - if num_method_types == 0 { |
299 |
| - struct_span_err!(self.tcx.sess, |
300 |
| - self.span, |
301 |
| - E0035, |
302 |
| - "does not take type parameters") |
303 |
| - .span_label(self.span, "called with unneeded type parameters") |
304 |
| - .emit(); |
305 |
| - } else { |
306 |
| - struct_span_err!(self.tcx.sess, |
307 |
| - self.span, |
308 |
| - E0036, |
309 |
| - "incorrect number of type parameters given for this method: \ |
310 |
| - expected {}, found {}", |
311 |
| - num_method_types, |
312 |
| - num_supplied_types) |
313 |
| - .span_label(self.span, |
314 |
| - format!("Passed {} type argument{}, expected {}", |
315 |
| - num_supplied_types, |
316 |
| - if num_supplied_types != 1 { "s" } else { "" }, |
317 |
| - num_method_types)) |
318 |
| - .emit(); |
319 |
| - } |
320 |
| - } |
| 290 | + let mut fn_segment = Some((segment, method_generics)); |
| 291 | + self.fcx.check_path_parameter_count(self.span, &mut fn_segment); |
321 | 292 |
|
322 | 293 | // Create subst for early-bound lifetime parameters, combining
|
323 | 294 | // parameters from the type and those from the method.
|
324 |
| - // |
325 |
| - // FIXME -- permit users to manually specify lifetimes |
326 |
| - let supplied_start = substs.len() + method_generics.regions.len(); |
| 295 | + let (supplied_types, supplied_lifetimes) = match segment.parameters { |
| 296 | + hir::AngleBracketedParameters(ref data) => (&data.types, &data.lifetimes), |
| 297 | + _ => bug!("unexpected generic arguments: {:?}", segment.parameters), |
| 298 | + }; |
327 | 299 | Substs::for_item(self.tcx, pick.item.def_id, |def, _| {
|
328 | 300 | let i = def.index as usize;
|
329 | 301 | if i < substs.len() {
|
330 | 302 | substs.region_at(i)
|
| 303 | + } else if let Some(lifetime) = supplied_lifetimes.get(i - substs.len()) { |
| 304 | + AstConv::ast_region_to_region(self.fcx, lifetime, Some(def)) |
331 | 305 | } else {
|
332 | 306 | self.region_var_for_def(self.span, def)
|
333 | 307 | }
|
334 | 308 | }, |def, cur_substs| {
|
335 | 309 | let i = def.index as usize;
|
336 | 310 | if i < substs.len() {
|
337 | 311 | substs.type_at(i)
|
338 |
| - } else if let Some(ast_ty) = supplied_method_types.get(i - supplied_start) { |
| 312 | + } else if let Some(ast_ty) = supplied_types.get(i - substs.len()) { |
339 | 313 | self.to_ty(ast_ty)
|
340 | 314 | } else {
|
341 | 315 | self.type_var_for_def(self.span, def, cur_substs)
|
|
0 commit comments