Skip to content

Commit a5328bc

Browse files
committed
Simply joint lifetime/type iteration
1 parent 8bccfe7 commit a5328bc

File tree

19 files changed

+122
-217
lines changed

19 files changed

+122
-217
lines changed

src/librustc/hir/mod.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -449,12 +449,6 @@ pub type TyParamBounds = HirVec<TyParamBound>;
449449
pub enum GenericParamKind {
450450
/// A lifetime definition, eg `'a: 'b + 'c + 'd`.
451451
Lifetime {
452-
/// Either "'a", referring to a named lifetime definition,
453-
/// or "" (aka keywords::Invalid), for elision placeholders.
454-
///
455-
/// HIR lowering inserts these placeholders in type paths that
456-
/// refer to type definitions needing lifetime parameters,
457-
/// `&T` and `&mut T`, and trait objects without `... + 'a`.
458452
name: LifetimeName,
459453
bounds: HirVec<Lifetime>,
460454
// Indicates that the lifetime definition was synthetically added

src/librustc_save_analysis/lib.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -934,10 +934,7 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
934934
sig.push_str(&generics
935935
.params
936936
.iter()
937-
.map(|param| match param.kind {
938-
ast::GenericParamKind::Lifetime { .. } => param.ident.name.to_string(),
939-
ast::GenericParamKind::Type { .. } => param.ident.to_string(),
940-
})
937+
.map(|param| param.ident.to_string())
941938
.collect::<Vec<_>>()
942939
.join(", "));
943940
sig.push_str("> ");

src/librustc_typeck/astconv.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -996,22 +996,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
996996
pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
997997
for segment in segments {
998998
segment.with_generic_args(|generic_args| {
999-
let mut err_for_lifetime = false;
1000-
let mut err_for_type = false;
999+
let (mut err_for_lt, mut err_for_ty) = (false, false);
10011000
for arg in &generic_args.args {
10021001
let (mut span_err, span, kind) = match arg {
10031002
hir::GenericArg::Lifetime(lt) => {
1004-
if err_for_lifetime { continue }
1005-
err_for_lifetime = true;
1003+
if err_for_lt { continue }
1004+
err_for_lt = true;
10061005
(struct_span_err!(self.tcx().sess, lt.span, E0110,
10071006
"lifetime parameters are not allowed on \
10081007
this type"),
10091008
lt.span,
10101009
"lifetime")
10111010
}
10121011
hir::GenericArg::Type(ty) => {
1013-
if err_for_type { continue }
1014-
err_for_type = true;
1012+
if err_for_ty { continue }
1013+
err_for_ty = true;
10151014
(struct_span_err!(self.tcx().sess, ty.span, E0109,
10161015
"type parameters are not allowed on this type"),
10171016
ty.span,
@@ -1020,7 +1019,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
10201019
};
10211020
span_err.span_label(span, format!("{} parameter not allowed", kind))
10221021
.emit();
1023-
if err_for_lifetime && err_for_type {
1022+
if err_for_lt && err_for_ty {
10241023
break;
10251024
}
10261025
}

src/librustc_typeck/check/method/confirm.rs

Lines changed: 20 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -329,46 +329,32 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
329329
if i < parent_substs.len() {
330330
parent_substs[i]
331331
} else {
332-
match param.kind {
333-
GenericParamDefKind::Lifetime => {
334-
if let Some(lifetime) = provided.as_ref().and_then(|data| {
335-
for arg in &data.args {
336-
match arg {
337-
GenericArg::Lifetime(lt) => {
338-
if i == parent_substs.len() {
339-
return Some(lt);
340-
}
341-
i -= 1;
342-
}
343-
_ => {}
332+
let (is_lt, is_ty) = match param.kind {
333+
GenericParamDefKind::Lifetime => (true, false),
334+
GenericParamDefKind::Type { .. } => (false, true),
335+
};
336+
provided.as_ref().and_then(|data| {
337+
for arg in &data.args {
338+
match arg {
339+
GenericArg::Lifetime(lt) if is_lt => {
340+
if i == parent_substs.len() {
341+
return Some(AstConv::ast_region_to_region(
342+
self.fcx, lt, Some(param)).into());
344343
}
344+
i -= 1;
345345
}
346-
None
347-
}) {
348-
return AstConv::ast_region_to_region(
349-
self.fcx, lifetime, Some(param)).into();
350-
}
351-
}
352-
GenericParamDefKind::Type {..} => {
353-
if let Some(ast_ty) = provided.as_ref().and_then(|data| {
354-
for arg in &data.args {
355-
match arg {
356-
GenericArg::Type(ty) => {
357-
if i == parent_substs.len() + own_counts.lifetimes {
358-
return Some(ty);
359-
}
360-
i -= 1;
361-
}
362-
_ => {}
346+
GenericArg::Lifetime(_) => {}
347+
GenericArg::Type(ty) if is_ty => {
348+
if i == parent_substs.len() + own_counts.lifetimes {
349+
return Some(self.to_ty(ty).into());
363350
}
351+
i -= 1;
364352
}
365-
None
366-
}) {
367-
return self.to_ty(ast_ty).into();
353+
GenericArg::Type(_) => {}
368354
}
369355
}
370-
}
371-
self.var_for_def(self.span, param)
356+
None
357+
}).unwrap_or_else(|| self.var_for_def(self.span, param))
372358
}
373359
})
374360
}

src/librustc_typeck/check/mod.rs

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4977,8 +4977,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49774977
s.args.as_ref().map_or(
49784978
(vec![], vec![], s.infer_types, &[][..]),
49794979
|data| {
4980-
let mut lifetimes = vec![];
4981-
let mut types = vec![];
4980+
let (mut lifetimes, mut types) = (vec![], vec![]);
49824981
data.args.iter().for_each(|arg| match arg {
49834982
GenericArg::Lifetime(lt) => lifetimes.push(lt),
49844983
GenericArg::Type(ty) => types.push(ty),
@@ -4987,14 +4986,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49874986
}
49884987
)
49894988
});
4990-
let infer_lifetimes = lifetimes.len() == 0;
4991-
4992-
let count_lifetime_params = |n| {
4993-
format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
4994-
};
4995-
let count_type_params = |n| {
4996-
format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
4997-
};
49984989

49994990
// Check provided parameters.
50004991
let ((ty_required, ty_accepted), lt_accepted) =
@@ -5008,9 +4999,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50084999
let mut ty_params = ParamRange { required: 0, accepted: 0 };
50095000
for param in &generics.params {
50105001
match param.kind {
5011-
GenericParamDefKind::Lifetime => {
5012-
lt_accepted += 1;
5013-
}
5002+
GenericParamDefKind::Lifetime => lt_accepted += 1,
50145003
GenericParamDefKind::Type { has_default, .. } => {
50155004
ty_params.accepted += 1;
50165005
if !has_default {
@@ -5027,36 +5016,37 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50275016
((ty_params.required, ty_params.accepted), lt_accepted)
50285017
});
50295018

5030-
if types.len() > ty_accepted {
5031-
let span = types[ty_accepted].span;
5032-
let expected_text = count_type_params(ty_accepted);
5033-
let actual_text = count_type_params(types.len());
5034-
struct_span_err!(self.tcx.sess, span, E0087,
5035-
"too many type parameters provided: \
5036-
expected at most {}, found {}",
5037-
expected_text, actual_text)
5038-
.span_label(span, format!("expected {}", expected_text))
5039-
.emit();
5040-
5019+
let count_type_params = |n| {
5020+
format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
5021+
};
5022+
let expected_text = count_type_params(ty_accepted);
5023+
let actual_text = count_type_params(types.len());
5024+
if let Some((mut err, span)) = if types.len() > ty_accepted {
50415025
// To prevent derived errors to accumulate due to extra
50425026
// type parameters, we force instantiate_value_path to
50435027
// use inference variables instead of the provided types.
50445028
*segment = None;
5029+
let span = types[ty_accepted].span;
5030+
Some((struct_span_err!(self.tcx.sess, span, E0087,
5031+
"too many type parameters provided: \
5032+
expected at most {}, found {}",
5033+
expected_text, actual_text), span))
50455034
} else if types.len() < ty_required && !infer_types && !supress_mismatch_error {
5046-
let expected_text = count_type_params(ty_required);
5047-
let actual_text = count_type_params(types.len());
5048-
struct_span_err!(self.tcx.sess, span, E0089,
5049-
"too few type parameters provided: \
5050-
expected {}, found {}",
5051-
expected_text, actual_text)
5052-
.span_label(span, format!("expected {}", expected_text))
5053-
.emit();
5035+
Some((struct_span_err!(self.tcx.sess, span, E0089,
5036+
"too few type parameters provided: \
5037+
expected {}, found {}",
5038+
expected_text, actual_text), span))
5039+
} else {
5040+
None
5041+
} {
5042+
err.span_label(span, format!("expected {}", expected_text)).emit();
50545043
}
50555044

50565045
if !bindings.is_empty() {
50575046
AstConv::prohibit_projection(self, bindings[0].span);
50585047
}
50595048

5049+
let infer_lifetimes = lifetimes.len() == 0;
50605050
// Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
50615051
let has_late_bound_lifetime_defs =
50625052
segment.map_or(None, |(_, generics)| generics.has_late_bound_regions);
@@ -5080,25 +5070,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
50805070
return;
50815071
}
50825072

5083-
if lifetimes.len() > lt_accepted {
5073+
let count_lifetime_params = |n| {
5074+
format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
5075+
};
5076+
let expected_text = count_lifetime_params(lt_accepted);
5077+
let actual_text = count_lifetime_params(lifetimes.len());
5078+
if let Some((mut err, span)) = if lifetimes.len() > lt_accepted {
50845079
let span = lifetimes[lt_accepted].span;
5085-
let expected_text = count_lifetime_params(lt_accepted);
5086-
let actual_text = count_lifetime_params(lifetimes.len());
5087-
struct_span_err!(self.tcx.sess, span, E0088,
5088-
"too many lifetime parameters provided: \
5089-
expected at most {}, found {}",
5090-
expected_text, actual_text)
5091-
.span_label(span, format!("expected {}", expected_text))
5092-
.emit();
5080+
Some((struct_span_err!(self.tcx.sess, span, E0088,
5081+
"too many lifetime parameters provided: \
5082+
expected at most {}, found {}",
5083+
expected_text, actual_text), span))
50935084
} else if lifetimes.len() < lt_accepted && !infer_lifetimes {
5094-
let expected_text = count_lifetime_params(lt_accepted);
5095-
let actual_text = count_lifetime_params(lifetimes.len());
5096-
struct_span_err!(self.tcx.sess, span, E0090,
5097-
"too few lifetime parameters provided: \
5098-
expected {}, found {}",
5099-
expected_text, actual_text)
5100-
.span_label(span, format!("expected {}", expected_text))
5101-
.emit();
5085+
Some((struct_span_err!(self.tcx.sess, span, E0090,
5086+
"too few lifetime parameters provided: \
5087+
expected {}, found {}",
5088+
expected_text, actual_text), span))
5089+
} else {
5090+
None
5091+
} {
5092+
err.span_label(span, format!("expected {}", expected_text)).emit();
51025093
}
51035094
}
51045095

src/librustc_typeck/check/wfcheck.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -660,15 +660,12 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
660660
fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
661661
let generics = tcx.generics_of(def_id);
662662
let parent = tcx.generics_of(generics.parent.unwrap());
663-
let impl_params: FxHashMap<_, _> =
664-
parent.params.iter()
665-
.flat_map(|param| match param.kind {
666-
GenericParamDefKind::Lifetime => None,
667-
GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
668-
})
669-
.collect();
670-
671-
for method_param in generics.params.iter() {
663+
let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
664+
GenericParamDefKind::Lifetime => None,
665+
GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
666+
}).collect();
667+
668+
for method_param in &generics.params {
672669
match method_param.kind {
673670
// Shadowing is checked in resolve_lifetime.
674671
GenericParamDefKind::Lifetime => continue,

src/librustc_typeck/coherence/unsafety.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,8 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
3535

3636
Some(trait_ref) => {
3737
let trait_def = self.tcx.trait_def(trait_ref.def_id);
38-
let unsafe_attr = impl_generics.and_then(|g| {
39-
for param in &g.params {
40-
if param.pure_wrt_drop {
41-
return Some("may_dangle");
42-
}
43-
}
44-
None
38+
let unsafe_attr = impl_generics.and_then(|generics| {
39+
generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
4540
});
4641
match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
4742
(Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {

src/librustc_typeck/collect.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,11 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
117117
for param in &generics.params {
118118
match param.kind {
119119
hir::GenericParamKind::Lifetime { .. } => {}
120-
hir::GenericParamKind::Type { ref default, .. } => {
121-
if default.is_some() {
122-
let def_id = self.tcx.hir.local_def_id(param.id);
123-
self.tcx.type_of(def_id);
124-
}
120+
hir::GenericParamKind::Type { ref default, .. } if default.is_some() => {
121+
let def_id = self.tcx.hir.local_def_id(param.id);
122+
self.tcx.type_of(def_id);
125123
}
124+
hir::GenericParamKind::Type { .. } => {}
126125
}
127126
}
128127
intravisit::walk_generics(self, generics);
@@ -316,11 +315,8 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
316315
let from_ty_params =
317316
ast_generics.params.iter()
318317
.filter_map(|param| match param.kind {
319-
GenericParamKind::Type { ref bounds, .. } => {
320-
if param.id == param_id {
321-
return Some(bounds);
322-
}
323-
None
318+
GenericParamKind::Type { ref bounds, .. } if param.id == param_id => {
319+
Some(bounds)
324320
}
325321
_ => None
326322
})
@@ -1470,11 +1466,8 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
14701466
.to_ty(tcx);
14711467
index += 1;
14721468

1473-
let bounds = compute_bounds(&icx,
1474-
param_ty,
1475-
bounds,
1476-
SizedByDefault::Yes,
1477-
param.span);
1469+
let bounds =
1470+
compute_bounds(&icx, param_ty, bounds, SizedByDefault::Yes, param.span);
14781471
predicates.extend(bounds.predicates(tcx, param_ty));
14791472
}
14801473
_ => {}

src/librustc_typeck/diagnostics.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,12 +1501,12 @@ struct Foo {
15011501
"##,
15021502

15031503
E0131: r##"
1504-
It is not possible to define `main` with type parameters, or even with function
1505-
parameters. When `main` is present, it must take no arguments and return `()`.
1504+
It is not possible to define `main` with generic parameters.
1505+
When `main` is present, it must take no arguments and return `()`.
15061506
Erroneous code example:
15071507
15081508
```compile_fail,E0131
1509-
fn main<T>() { // error: main function is not allowed to have type parameters
1509+
fn main<T>() { // error: main function is not allowed to have generic parameters
15101510
}
15111511
```
15121512
"##,

src/librustc_typeck/lib.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,9 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
191191
hir::ItemFn(.., ref generics, _) => {
192192
let mut error = false;
193193
if !generics.params.is_empty() {
194-
let param_type = if generics.is_lt_parameterized() {
195-
"lifetime"
196-
} else {
197-
"type"
198-
};
199-
let msg =
200-
format!("`main` function is not allowed to have {} parameters",
201-
param_type);
202-
let label =
203-
format!("`main` cannot have {} parameters", param_type);
194+
let msg = format!("`main` function is not allowed to have generic \
195+
parameters");
196+
let label = format!("`main` cannot have generic parameters");
204197
struct_span_err!(tcx.sess, generics.span, E0131, "{}", msg)
205198
.span_label(generics.span, label)
206199
.emit();

0 commit comments

Comments
 (0)