Skip to content

Commit ab57988

Browse files
committed
Factor out the "region substs" creation to occur earlier, so that the
complete set of regions are available when converting types.
1 parent 80d1f14 commit ab57988

File tree

1 file changed

+82
-43
lines changed

1 file changed

+82
-43
lines changed

src/librustc_typeck/astconv.rs

Lines changed: 82 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -264,34 +264,31 @@ pub fn ast_path_substs_for_ty<'tcx>(
264264

265265
let (regions, types, assoc_bindings) = match path.segments.last().unwrap().parameters {
266266
ast::AngleBracketedParameters(ref data) => {
267-
convert_angle_bracketed_parameters(this, rscope, data)
267+
convert_angle_bracketed_parameters(this, rscope, path.span, decl_generics, data)
268268
}
269269
ast::ParenthesizedParameters(ref data) => {
270270
span_err!(tcx.sess, path.span, E0214,
271271
"parenthesized parameters may only be used with a trait");
272-
convert_parenthesized_parameters(this, data)
272+
convert_parenthesized_parameters(this, rscope, path.span, decl_generics, data)
273273
}
274274
};
275275

276276
prohibit_projections(this.tcx(), &assoc_bindings);
277277

278278
create_substs_for_ast_path(this,
279-
rscope,
280279
path.span,
281280
decl_generics,
282281
None,
283282
types,
284283
regions)
285284
}
286285

287-
fn create_substs_for_ast_path<'tcx>(
286+
fn create_region_substs<'tcx>(
288287
this: &AstConv<'tcx>,
289288
rscope: &RegionScope,
290289
span: Span,
291290
decl_generics: &ty::Generics<'tcx>,
292-
self_ty: Option<Ty<'tcx>>,
293-
types: Vec<Ty<'tcx>>,
294-
regions: Vec<ty::Region>)
291+
regions_provided: Vec<ty::Region>)
295292
-> Substs<'tcx>
296293
{
297294
let tcx = this.tcx();
@@ -300,9 +297,9 @@ fn create_substs_for_ast_path<'tcx>(
300297
// region with the current anon region binding (in other words,
301298
// whatever & would get replaced with).
302299
let expected_num_region_params = decl_generics.regions.len(TypeSpace);
303-
let supplied_num_region_params = regions.len();
300+
let supplied_num_region_params = regions_provided.len();
304301
let regions = if expected_num_region_params == supplied_num_region_params {
305-
regions
302+
regions_provided
306303
} else {
307304
let anon_regions =
308305
rscope.anon_regions(span, expected_num_region_params);
@@ -314,51 +311,82 @@ fn create_substs_for_ast_path<'tcx>(
314311
}
315312

316313
match anon_regions {
317-
Ok(v) => v.into_iter().collect(),
318-
Err(_) => (0..expected_num_region_params)
319-
.map(|_| ty::ReStatic).collect() // hokey
314+
Ok(anon_regions) => anon_regions,
315+
Err(_) => (0..expected_num_region_params).map(|_| ty::ReStatic).collect()
320316
}
321317
};
318+
Substs::new_type(vec![], regions)
319+
}
320+
321+
/// Given the type/region arguments provided to some path (along with
322+
/// an implicit Self, if this is a trait reference) returns the complete
323+
/// set of substitutions. This may involve applying defaulted type parameters.
324+
///
325+
/// Note that the type listing given here is *exactly* what the user provided.
326+
///
327+
/// The `region_substs` should be the result of `create_region_substs`
328+
/// -- that is, a substitution with no types but the correct number of
329+
/// regions.
330+
fn create_substs_for_ast_path<'tcx>(
331+
this: &AstConv<'tcx>,
332+
span: Span,
333+
decl_generics: &ty::Generics<'tcx>,
334+
self_ty: Option<Ty<'tcx>>,
335+
types_provided: Vec<Ty<'tcx>>,
336+
region_substs: Substs<'tcx>)
337+
-> Substs<'tcx>
338+
{
339+
let tcx = this.tcx();
340+
341+
debug!("create_substs_for_ast_path(decl_generics={}, self_ty={}, \
342+
types_provided={}, region_substs={}",
343+
decl_generics.repr(tcx), self_ty.repr(tcx), types_provided.repr(tcx),
344+
region_substs.repr(tcx));
345+
346+
assert_eq!(region_substs.regions().len(TypeSpace), decl_generics.regions.len(TypeSpace));
347+
assert!(region_substs.types.is_empty());
322348

323349
// Convert the type parameters supplied by the user.
324350
let ty_param_defs = decl_generics.types.get_slice(TypeSpace);
325-
let supplied_ty_param_count = types.len();
326-
let formal_ty_param_count =
327-
ty_param_defs.iter()
328-
.take_while(|x| !ty::is_associated_type(tcx, x.def_id))
329-
.count();
330-
let required_ty_param_count =
331-
ty_param_defs.iter()
332-
.take_while(|x| {
333-
x.default.is_none() &&
334-
!ty::is_associated_type(tcx, x.def_id)
335-
})
336-
.count();
351+
let supplied_ty_param_count = types_provided.len();
352+
let formal_ty_param_count = ty_param_defs.len();
353+
let required_ty_param_count = ty_param_defs.iter()
354+
.take_while(|x| x.default.is_none())
355+
.count();
356+
357+
let mut type_substs = types_provided;
337358
if supplied_ty_param_count < required_ty_param_count {
338359
let expected = if required_ty_param_count < formal_ty_param_count {
339360
"expected at least"
340361
} else {
341362
"expected"
342363
};
343-
span_fatal!(this.tcx().sess, span, E0243,
344-
"wrong number of type arguments: {} {}, found {}",
345-
expected,
346-
required_ty_param_count,
347-
supplied_ty_param_count);
364+
span_err!(this.tcx().sess, span, E0243,
365+
"wrong number of type arguments: {} {}, found {}",
366+
expected,
367+
required_ty_param_count,
368+
supplied_ty_param_count);
369+
while type_substs.len() < required_ty_param_count {
370+
type_substs.push(tcx.types.err);
371+
}
348372
} else if supplied_ty_param_count > formal_ty_param_count {
349373
let expected = if required_ty_param_count < formal_ty_param_count {
350374
"expected at most"
351375
} else {
352376
"expected"
353377
};
354-
span_fatal!(this.tcx().sess, span, E0244,
355-
"wrong number of type arguments: {} {}, found {}",
356-
expected,
357-
formal_ty_param_count,
358-
supplied_ty_param_count);
378+
span_err!(this.tcx().sess, span, E0244,
379+
"wrong number of type arguments: {} {}, found {}",
380+
expected,
381+
formal_ty_param_count,
382+
supplied_ty_param_count);
383+
type_substs.truncate(formal_ty_param_count);
359384
}
385+
assert!(type_substs.len() >= required_ty_param_count &&
386+
type_substs.len() <= formal_ty_param_count);
360387

361-
let mut substs = Substs::new_type(types, regions);
388+
let mut substs = region_substs;
389+
substs.types.extend(TypeSpace, type_substs.into_iter());
362390

363391
match self_ty {
364392
None => {
@@ -374,7 +402,8 @@ fn create_substs_for_ast_path<'tcx>(
374402
}
375403
}
376404

377-
for param in &ty_param_defs[supplied_ty_param_count..] {
405+
let actual_supplied_ty_param_count = substs.types.len(TypeSpace);
406+
for param in &ty_param_defs[actual_supplied_ty_param_count..] {
378407
match param.default {
379408
Some(default) => {
380409
// This is a default type parameter.
@@ -400,8 +429,10 @@ struct ConvertedBinding<'tcx> {
400429

401430
fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>,
402431
rscope: &RegionScope,
432+
span: Span,
433+
decl_generics: &ty::Generics<'tcx>,
403434
data: &ast::AngleBracketedParameterData)
404-
-> (Vec<ty::Region>,
435+
-> (Substs<'tcx>,
405436
Vec<Ty<'tcx>>,
406437
Vec<ConvertedBinding<'tcx>>)
407438
{
@@ -410,6 +441,9 @@ fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>,
410441
.map(|l| ast_region_to_region(this.tcx(), l))
411442
.collect();
412443

444+
let region_substs =
445+
create_region_substs(this, rscope, span, decl_generics, regions);
446+
413447
let types: Vec<_> =
414448
data.types.iter()
415449
.map(|t| ast_ty_to_ty(this, rscope, &**t))
@@ -422,7 +456,7 @@ fn convert_angle_bracketed_parameters<'tcx>(this: &AstConv<'tcx>,
422456
span: b.span })
423457
.collect();
424458

425-
(regions, types, assoc_bindings)
459+
(region_substs, types, assoc_bindings)
426460
}
427461

428462
/// Returns the appropriate lifetime to use for any output lifetimes
@@ -479,11 +513,17 @@ fn convert_ty_with_lifetime_elision<'tcx>(this: &AstConv<'tcx>,
479513
}
480514

481515
fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>,
516+
rscope: &RegionScope,
517+
span: Span,
518+
decl_generics: &ty::Generics<'tcx>,
482519
data: &ast::ParenthesizedParameterData)
483-
-> (Vec<ty::Region>,
520+
-> (Substs<'tcx>,
484521
Vec<Ty<'tcx>>,
485522
Vec<ConvertedBinding<'tcx>>)
486523
{
524+
let region_substs =
525+
create_region_substs(this, rscope, span, decl_generics, Vec::new());
526+
487527
let binding_rscope = BindingRscope::new();
488528
let inputs = data.inputs.iter()
489529
.map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t))
@@ -514,7 +554,7 @@ fn convert_parenthesized_parameters<'tcx>(this: &AstConv<'tcx>,
514554
span: output_span
515555
};
516556

517-
(vec![], vec![input_ty], vec![output_binding])
557+
(region_substs, vec![input_ty], vec![output_binding])
518558
}
519559

520560
pub fn instantiate_poly_trait_ref<'tcx>(
@@ -626,7 +666,7 @@ fn ast_path_to_trait_ref<'a,'tcx>(
626666
the crate attributes to enable");
627667
}
628668

629-
convert_angle_bracketed_parameters(this, rscope, data)
669+
convert_angle_bracketed_parameters(this, rscope, path.span, &trait_def.generics, data)
630670
}
631671
ast::ParenthesizedParameters(ref data) => {
632672
// For now, require that parenthetical notation be used
@@ -640,12 +680,11 @@ fn ast_path_to_trait_ref<'a,'tcx>(
640680
the crate attributes to enable");
641681
}
642682

643-
convert_parenthesized_parameters(this, data)
683+
convert_parenthesized_parameters(this, rscope, path.span, &trait_def.generics, data)
644684
}
645685
};
646686

647687
let substs = create_substs_for_ast_path(this,
648-
rscope,
649688
path.span,
650689
&trait_def.generics,
651690
self_ty,

0 commit comments

Comments
 (0)