Skip to content

Commit b575c18

Browse files
committed
Refactoring generic counting loops
1 parent fe1f651 commit b575c18

File tree

5 files changed

+71
-67
lines changed

5 files changed

+71
-67
lines changed

src/librustc/ty/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,7 @@ impl<'a, 'gcx, 'tcx> Generics {
803803
types: 0,
804804
};
805805

806-
for param in self.params.iter() {
806+
for param in &self.params {
807807
match param.kind {
808808
GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
809809
GenericParamDefKind::Type(_) => own_counts.types += 1,
@@ -814,7 +814,7 @@ impl<'a, 'gcx, 'tcx> Generics {
814814
}
815815

816816
pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
817-
for param in self.params.iter() {
817+
for param in &self.params {
818818
match param.kind {
819819
GenericParamDefKind::Type(_) => return true,
820820
GenericParamDefKind::Lifetime => {}

src/librustc_typeck/astconv.rs

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -208,40 +208,39 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
208208
// region with the current anon region binding (in other words,
209209
// whatever & would get replaced with).
210210
let decl_generics = tcx.generics_of(def_id);
211-
let own_counts = decl_generics.own_counts();
212-
let num_types_provided = parameters.types.len();
213-
let expected_num_region_params = own_counts.lifetimes;
214-
let supplied_num_region_params = parameters.lifetimes.len();
215-
if expected_num_region_params != supplied_num_region_params {
216-
report_lifetime_number_error(tcx, span,
217-
supplied_num_region_params,
218-
expected_num_region_params);
211+
let ty_provided = parameters.types.len();
212+
let lt_provided = parameters.lifetimes.len();
213+
214+
let mut lt_accepted = 0;
215+
let mut ty_range = (0, 0);
216+
for param in &decl_generics.params {
217+
match param.kind {
218+
GenericParamDefKind::Lifetime => {
219+
lt_accepted += 1;
220+
}
221+
GenericParamDefKind::Type(ty) => {
222+
ty_range.1 += 1;
223+
if !ty.has_default {
224+
ty_range.0 += 1;
225+
}
226+
}
227+
};
228+
}
229+
if self_ty.is_some() {
230+
ty_range.0 -= 1;
231+
ty_range.1 -= 1;
232+
}
233+
234+
if lt_accepted != lt_provided {
235+
report_lifetime_number_error(tcx, span, lt_provided, lt_accepted);
219236
}
220237

221238
// If a self-type was declared, one should be provided.
222239
assert_eq!(decl_generics.has_self, self_ty.is_some());
223240

224241
// Check the number of type parameters supplied by the user.
225-
let own_self = self_ty.is_some() as usize;
226-
let ty_param_defs = own_counts.types - own_self;
227-
if !infer_types || num_types_provided > ty_param_defs {
228-
let type_params_without_defaults = {
229-
let mut count = 0;
230-
for param in decl_generics.params.iter() {
231-
if let ty::GenericParamDefKind::Type(ty) = param.kind {
232-
if !ty.has_default {
233-
count += 1
234-
}
235-
}
236-
}
237-
count
238-
};
239-
240-
check_type_argument_count(tcx,
241-
span,
242-
num_types_provided,
243-
ty_param_defs,
244-
type_params_without_defaults - own_self);
242+
if !infer_types || ty_provided > ty_range.0 {
243+
check_type_argument_count(tcx, span, ty_provided, ty_range);
245244
}
246245

247246
let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF);
@@ -259,6 +258,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
259258
false
260259
};
261260

261+
let own_self = self_ty.is_some() as usize;
262262
let substs = Substs::for_item(tcx, def_id, |def, _| {
263263
let i = def.index as usize - own_self;
264264
if let Some(lifetime) = parameters.lifetimes.get(i) {
@@ -279,8 +279,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
279279
_ => unreachable!()
280280
};
281281

282-
let i = i - (own_counts.lifetimes + own_self);
283-
if i < num_types_provided {
282+
let i = i - (lt_accepted + own_self);
283+
if i < ty_provided {
284284
// A provided type parameter.
285285
self.ast_ty_to_ty(&parameters.types[i])
286286
} else if infer_types {
@@ -1327,11 +1327,9 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
13271327
fn check_type_argument_count(tcx: TyCtxt,
13281328
span: Span,
13291329
supplied: usize,
1330-
ty_param_defs: usize,
1331-
ty_param_defs_without_default: usize)
1330+
ty_range: (usize, usize))
13321331
{
1333-
let accepted = ty_param_defs;
1334-
let required = ty_param_defs_without_default;
1332+
let (required, accepted) = ty_range;
13351333
if supplied < required {
13361334
let expected = if required < accepted {
13371335
"expected at least"

src/librustc_typeck/check/mod.rs

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4923,32 +4923,34 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49234923
};
49244924

49254925
// Check provided parameters.
4926-
let (ty_req_len, accepted, lt_req_len) =
4927-
segment.map_or((0, 0, 0), |(_, generics)| {
4928-
let own_counts = generics.own_counts();
4929-
4930-
let own_self = (generics.parent.is_none() && generics.has_self) as usize;
4931-
let type_params = own_counts.types - own_self;
4932-
let type_params_without_defaults = {
4933-
let mut count = 0;
4934-
for param in generics.params.iter() {
4935-
if let ty::GenericParamDefKind::Type(ty) = param.kind {
4926+
let ((ty_required, ty_accepted), lt_accepted) =
4927+
segment.map_or(((0, 0), 0), |(_, generics)| {
4928+
let mut lt_accepted = 0;
4929+
let mut ty_range = (0, 0);
4930+
for param in &generics.params {
4931+
match param.kind {
4932+
GenericParamDefKind::Lifetime => {
4933+
lt_accepted += 1;
4934+
}
4935+
GenericParamDefKind::Type(ty) => {
4936+
ty_range.1 += 1;
49364937
if !ty.has_default {
4937-
count += 1
4938+
ty_range.0 += 1;
49384939
}
49394940
}
4940-
}
4941-
count
4942-
};
4943-
let type_params_barring_defaults =
4944-
type_params_without_defaults - own_self;
4941+
};
4942+
}
4943+
if generics.parent.is_none() && generics.has_self {
4944+
ty_range.0 -= 1;
4945+
ty_range.1 -= 1;
4946+
}
49454947

4946-
(type_params_barring_defaults, type_params, own_counts.lifetimes)
4948+
((ty_range.0, ty_range.1), lt_accepted)
49474949
});
49484950

4949-
if types.len() > accepted {
4950-
let span = types[accepted].span;
4951-
let expected_text = count_type_params(accepted);
4951+
if types.len() > ty_accepted {
4952+
let span = types[ty_accepted].span;
4953+
let expected_text = count_type_params(ty_accepted);
49524954
let actual_text = count_type_params(types.len());
49534955
struct_span_err!(self.tcx.sess, span, E0087,
49544956
"too many type parameters provided: \
@@ -4961,8 +4963,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49614963
// type parameters, we force instantiate_value_path to
49624964
// use inference variables instead of the provided types.
49634965
*segment = None;
4964-
} else if types.len() < ty_req_len && !infer_types && !supress_mismatch_error {
4965-
let expected_text = count_type_params(ty_req_len);
4966+
} else if types.len() < ty_required && !infer_types && !supress_mismatch_error {
4967+
let expected_text = count_type_params(ty_required);
49664968
let actual_text = count_type_params(types.len());
49674969
struct_span_err!(self.tcx.sess, span, E0089,
49684970
"too few type parameters provided: \
@@ -4984,8 +4986,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49844986
let primary_msg = "cannot specify lifetime arguments explicitly \
49854987
if late bound lifetime parameters are present";
49864988
let note_msg = "the late bound lifetime parameter is introduced here";
4987-
if !is_method_call && (lifetimes.len() > lt_req_len ||
4988-
lifetimes.len() < lt_req_len && !infer_lifetimes) {
4989+
if !is_method_call && (lifetimes.len() > lt_accepted ||
4990+
lifetimes.len() < lt_accepted && !infer_lifetimes) {
49894991
let mut err = self.tcx.sess.struct_span_err(lifetimes[0].span, primary_msg);
49904992
err.span_note(span_late, note_msg);
49914993
err.emit();
@@ -4999,18 +5001,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
49995001
return;
50005002
}
50015003

5002-
if lifetimes.len() > lt_req_len {
5003-
let span = lifetimes[lt_req_len].span;
5004-
let expected_text = count_lifetime_params(lt_req_len);
5004+
if lifetimes.len() > lt_accepted {
5005+
let span = lifetimes[lt_accepted].span;
5006+
let expected_text = count_lifetime_params(lt_accepted);
50055007
let actual_text = count_lifetime_params(lifetimes.len());
50065008
struct_span_err!(self.tcx.sess, span, E0088,
50075009
"too many lifetime parameters provided: \
50085010
expected at most {}, found {}",
50095011
expected_text, actual_text)
50105012
.span_label(span, format!("expected {}", expected_text))
50115013
.emit();
5012-
} else if lifetimes.len() < lt_req_len && !infer_lifetimes {
5013-
let expected_text = count_lifetime_params(lt_req_len);
5014+
} else if lifetimes.len() < lt_accepted && !infer_lifetimes {
5015+
let expected_text = count_lifetime_params(lt_accepted);
50145016
let actual_text = count_lifetime_params(lifetimes.len());
50155017
struct_span_err!(self.tcx.sess, span, E0090,
50165018
"too few lifetime parameters provided: \

src/librustc_typeck/collect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
903903
let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id);
904904

905905
// Now create the real type parameters.
906-
let type_start = params.len() as u32;
906+
let type_start = own_start - has_self as u32 + params.len() as u32;
907907
params.extend(ast_generics.ty_params().enumerate().map(|(i, p)| {
908908
if p.name == keywords::SelfType.name() {
909909
span_bug!(p.span, "`Self` should not be the name of a regular parameter");

src/librustdoc/clean/mod.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1339,11 +1339,15 @@ impl Clean<TyParam> for hir::TyParam {
13391339
impl<'tcx> Clean<TyParam> for ty::GenericParamDef {
13401340
fn clean(&self, cx: &DocContext) -> TyParam {
13411341
cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
1342+
let has_default = match self.kind {
1343+
ty::GenericParamDefKind::Type(ty) => ty.has_default,
1344+
_ => panic!("tried to convert a non-type GenericParamDef as a type")
1345+
};
13421346
TyParam {
13431347
name: self.name.clean(cx),
13441348
did: self.def_id,
13451349
bounds: vec![], // these are filled in from the where-clauses
1346-
default: if self.to_type().has_default {
1350+
default: if has_default {
13471351
Some(cx.tcx.type_of(self.def_id).clean(cx))
13481352
} else {
13491353
None

0 commit comments

Comments
 (0)