about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-05-11 16:12:56 +0100
committervarkor <github@varkor.com>2018-05-15 14:21:32 +0100
commitb575c18992394f9723ddacee49665351874c7b30 (patch)
tree5061c717adb31d873b2a8388ffcb489669718e4f
parentfe1f651e4c28bb39da739f1433d94c6ed6caec82 (diff)
downloadrust-b575c18992394f9723ddacee49665351874c7b30.tar.gz
rust-b575c18992394f9723ddacee49665351874c7b30.zip
Refactoring generic counting loops
-rw-r--r--src/librustc/ty/mod.rs4
-rw-r--r--src/librustc_typeck/astconv.rs66
-rw-r--r--src/librustc_typeck/check/mod.rs60
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustdoc/clean/mod.rs6
5 files changed, 71 insertions, 67 deletions
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index fc085cbd4f8..4818006b9e7 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -803,7 +803,7 @@ impl<'a, 'gcx, 'tcx> Generics {
             types: 0,
         };
 
-        for param in self.params.iter() {
+        for param in &self.params {
             match param.kind {
                 GenericParamDefKind::Lifetime => own_counts.lifetimes += 1,
                 GenericParamDefKind::Type(_) => own_counts.types += 1,
@@ -814,7 +814,7 @@ impl<'a, 'gcx, 'tcx> Generics {
     }
 
     pub fn requires_monomorphization(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool {
-        for param in self.params.iter() {
+        for param in &self.params {
             match param.kind {
                 GenericParamDefKind::Type(_) => return true,
                 GenericParamDefKind::Lifetime => {}
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 50d76d81790..ec685dd8c4c 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -208,40 +208,39 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         // region with the current anon region binding (in other words,
         // whatever & would get replaced with).
         let decl_generics = tcx.generics_of(def_id);
-        let own_counts = decl_generics.own_counts();
-        let num_types_provided = parameters.types.len();
-        let expected_num_region_params = own_counts.lifetimes;
-        let supplied_num_region_params = parameters.lifetimes.len();
-        if expected_num_region_params != supplied_num_region_params {
-            report_lifetime_number_error(tcx, span,
-                                         supplied_num_region_params,
-                                         expected_num_region_params);
+        let ty_provided = parameters.types.len();
+        let lt_provided = parameters.lifetimes.len();
+
+        let mut lt_accepted = 0;
+        let mut ty_range = (0, 0);
+        for param in &decl_generics.params {
+            match param.kind {
+                GenericParamDefKind::Lifetime => {
+                    lt_accepted += 1;
+                }
+                GenericParamDefKind::Type(ty) => {
+                    ty_range.1 += 1;
+                    if !ty.has_default {
+                        ty_range.0 += 1;
+                    }
+                }
+            };
+        }
+        if self_ty.is_some() {
+            ty_range.0 -= 1;
+            ty_range.1 -= 1;
+        }
+
+        if lt_accepted != lt_provided {
+            report_lifetime_number_error(tcx, span, lt_provided, lt_accepted);
         }
 
         // If a self-type was declared, one should be provided.
         assert_eq!(decl_generics.has_self, self_ty.is_some());
 
         // Check the number of type parameters supplied by the user.
-        let own_self = self_ty.is_some() as usize;
-        let ty_param_defs = own_counts.types - own_self;
-        if !infer_types || num_types_provided > ty_param_defs {
-            let type_params_without_defaults = {
-                let mut count = 0;
-                for param in decl_generics.params.iter() {
-                    if let ty::GenericParamDefKind::Type(ty) = param.kind {
-                        if !ty.has_default {
-                            count += 1
-                        }
-                    }
-                }
-                count
-            };
-
-            check_type_argument_count(tcx,
-                span,
-                num_types_provided,
-                ty_param_defs,
-                type_params_without_defaults - own_self);
+        if !infer_types || ty_provided > ty_range.0 {
+            check_type_argument_count(tcx, span, ty_provided, ty_range);
         }
 
         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 {
             false
         };
 
+        let own_self = self_ty.is_some() as usize;
         let substs = Substs::for_item(tcx, def_id, |def, _| {
             let i = def.index as usize - own_self;
             if let Some(lifetime) = parameters.lifetimes.get(i) {
@@ -279,8 +279,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                 _ => unreachable!()
             };
 
-            let i = i - (own_counts.lifetimes + own_self);
-            if i < num_types_provided {
+            let i = i - (lt_accepted + own_self);
+            if i < ty_provided {
                 // A provided type parameter.
                 self.ast_ty_to_ty(&parameters.types[i])
             } else if infer_types {
@@ -1327,11 +1327,9 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
 fn check_type_argument_count(tcx: TyCtxt,
                              span: Span,
                              supplied: usize,
-                             ty_param_defs: usize,
-                             ty_param_defs_without_default: usize)
+                             ty_range: (usize, usize))
 {
-    let accepted = ty_param_defs;
-    let required = ty_param_defs_without_default;
+    let (required, accepted) = ty_range;
     if supplied < required {
         let expected = if required < accepted {
             "expected at least"
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 2ff760726d2..70d29c60a10 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4923,32 +4923,34 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         };
 
         // Check provided parameters.
-        let (ty_req_len, accepted, lt_req_len) =
-            segment.map_or((0, 0, 0), |(_, generics)| {
-                let own_counts = generics.own_counts();
-
-                let own_self = (generics.parent.is_none() && generics.has_self) as usize;
-                let type_params = own_counts.types - own_self;
-                let type_params_without_defaults = {
-                    let mut count = 0;
-                    for param in generics.params.iter() {
-                        if let ty::GenericParamDefKind::Type(ty) = param.kind {
+        let ((ty_required, ty_accepted), lt_accepted) =
+            segment.map_or(((0, 0), 0), |(_, generics)| {
+                let mut lt_accepted = 0;
+                let mut ty_range = (0, 0);
+                for param in &generics.params {
+                    match param.kind {
+                        GenericParamDefKind::Lifetime => {
+                            lt_accepted += 1;
+                        }
+                        GenericParamDefKind::Type(ty) => {
+                            ty_range.1 += 1;
                             if !ty.has_default {
-                                count += 1
+                                ty_range.0 += 1;
                             }
                         }
-                    }
-                    count
-                };
-                let type_params_barring_defaults =
-                    type_params_without_defaults - own_self;
+                    };
+                }
+                if generics.parent.is_none() && generics.has_self {
+                    ty_range.0 -= 1;
+                    ty_range.1 -= 1;
+                }
 
-                (type_params_barring_defaults, type_params, own_counts.lifetimes)
+                ((ty_range.0, ty_range.1), lt_accepted)
             });
 
-        if types.len() > accepted {
-            let span = types[accepted].span;
-            let expected_text = count_type_params(accepted);
+        if types.len() > ty_accepted {
+            let span = types[ty_accepted].span;
+            let expected_text = count_type_params(ty_accepted);
             let actual_text = count_type_params(types.len());
             struct_span_err!(self.tcx.sess, span, E0087,
                              "too many type parameters provided: \
@@ -4961,8 +4963,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             // type parameters, we force instantiate_value_path to
             // use inference variables instead of the provided types.
             *segment = None;
-        } else if types.len() < ty_req_len && !infer_types && !supress_mismatch_error {
-            let expected_text = count_type_params(ty_req_len);
+        } else if types.len() < ty_required && !infer_types && !supress_mismatch_error {
+            let expected_text = count_type_params(ty_required);
             let actual_text = count_type_params(types.len());
             struct_span_err!(self.tcx.sess, span, E0089,
                              "too few type parameters provided: \
@@ -4984,8 +4986,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             let primary_msg = "cannot specify lifetime arguments explicitly \
                                if late bound lifetime parameters are present";
             let note_msg = "the late bound lifetime parameter is introduced here";
-            if !is_method_call && (lifetimes.len() > lt_req_len ||
-                                   lifetimes.len() < lt_req_len && !infer_lifetimes) {
+            if !is_method_call && (lifetimes.len() > lt_accepted ||
+                                   lifetimes.len() < lt_accepted && !infer_lifetimes) {
                 let mut err = self.tcx.sess.struct_span_err(lifetimes[0].span, primary_msg);
                 err.span_note(span_late, note_msg);
                 err.emit();
@@ -4999,9 +5001,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             return;
         }
 
-        if lifetimes.len() > lt_req_len {
-            let span = lifetimes[lt_req_len].span;
-            let expected_text = count_lifetime_params(lt_req_len);
+        if lifetimes.len() > lt_accepted {
+            let span = lifetimes[lt_accepted].span;
+            let expected_text = count_lifetime_params(lt_accepted);
             let actual_text = count_lifetime_params(lifetimes.len());
             struct_span_err!(self.tcx.sess, span, E0088,
                              "too many lifetime parameters provided: \
@@ -5009,8 +5011,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                              expected_text, actual_text)
                 .span_label(span, format!("expected {}", expected_text))
                 .emit();
-        } else if lifetimes.len() < lt_req_len && !infer_lifetimes {
-            let expected_text = count_lifetime_params(lt_req_len);
+        } else if lifetimes.len() < lt_accepted && !infer_lifetimes {
+            let expected_text = count_lifetime_params(lt_accepted);
             let actual_text = count_lifetime_params(lifetimes.len());
             struct_span_err!(self.tcx.sess, span, E0090,
                              "too few lifetime parameters provided: \
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 4ddbe584846..d4f9fb948fe 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -903,7 +903,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id);
 
     // Now create the real type parameters.
-    let type_start = params.len() as u32;
+    let type_start = own_start - has_self as u32 + params.len() as u32;
     params.extend(ast_generics.ty_params().enumerate().map(|(i, p)| {
         if p.name == keywords::SelfType.name() {
             span_bug!(p.span, "`Self` should not be the name of a regular parameter");
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 621ec641ee0..17f2c47562f 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1339,11 +1339,15 @@ impl Clean<TyParam> for hir::TyParam {
 impl<'tcx> Clean<TyParam> for ty::GenericParamDef {
     fn clean(&self, cx: &DocContext) -> TyParam {
         cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
+        let has_default = match self.kind {
+            ty::GenericParamDefKind::Type(ty) => ty.has_default,
+            _ => panic!("tried to convert a non-type GenericParamDef as a type")
+        };
         TyParam {
             name: self.name.clean(cx),
             did: self.def_id,
             bounds: vec![], // these are filled in from the where-clauses
-            default: if self.to_type().has_default {
+            default: if has_default {
                 Some(cx.tcx.type_of(self.def_id).clean(cx))
             } else {
                 None