about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-05-27 21:54:10 +0100
committervarkor <github@varkor.com>2018-06-20 12:21:52 +0100
commita5328bc17b8d18083478554b3381d55183647f15 (patch)
tree5bda15e6c7620f1edc09254dd5283c2822b35cf7
parent8bccfe7a526bb03fd656a194a03f6850e16bc4c6 (diff)
downloadrust-a5328bc17b8d18083478554b3381d55183647f15.tar.gz
rust-a5328bc17b8d18083478554b3381d55183647f15.zip
Simply joint lifetime/type iteration
-rw-r--r--src/librustc/hir/mod.rs6
-rw-r--r--src/librustc_save_analysis/lib.rs5
-rw-r--r--src/librustc_typeck/astconv.rs13
-rw-r--r--src/librustc_typeck/check/method/confirm.rs54
-rw-r--r--src/librustc_typeck/check/mod.rs89
-rw-r--r--src/librustc_typeck/check/wfcheck.rs15
-rw-r--r--src/librustc_typeck/coherence/unsafety.rs9
-rw-r--r--src/librustc_typeck/collect.rs23
-rw-r--r--src/librustc_typeck/diagnostics.rs6
-rw-r--r--src/librustc_typeck/lib.rs13
-rw-r--r--src/librustdoc/clean/mod.rs12
-rw-r--r--src/libsyntax/visit.rs2
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs37
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs41
-rw-r--r--src/libsyntax_ext/env.rs2
-rw-r--r--src/test/compile-fail/issue-1900.rs2
-rw-r--r--src/test/ui/error-codes/E0131.stderr4
-rw-r--r--src/test/ui/issue-51022.rs2
-rw-r--r--src/test/ui/issue-51022.stderr4
19 files changed, 122 insertions, 217 deletions
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 9c2aa3c7e49..135403c9c27 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -449,12 +449,6 @@ pub type TyParamBounds = HirVec<TyParamBound>;
 pub enum GenericParamKind {
     /// A lifetime definition, eg `'a: 'b + 'c + 'd`.
     Lifetime {
-        /// Either "'a", referring to a named lifetime definition,
-        /// or "" (aka keywords::Invalid), for elision placeholders.
-        ///
-        /// HIR lowering inserts these placeholders in type paths that
-        /// refer to type definitions needing lifetime parameters,
-        /// `&T` and `&mut T`, and trait objects without `... + 'a`.
         name: LifetimeName,
         bounds: HirVec<Lifetime>,
         // Indicates that the lifetime definition was synthetically added
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 528f6ba96fa..453500d5ab7 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -934,10 +934,7 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
         sig.push_str(&generics
             .params
             .iter()
-            .map(|param| match param.kind {
-                ast::GenericParamKind::Lifetime { .. } => param.ident.name.to_string(),
-                ast::GenericParamKind::Type { .. } => param.ident.to_string(),
-            })
+            .map(|param| param.ident.to_string())
             .collect::<Vec<_>>()
             .join(", "));
         sig.push_str("> ");
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 9d38865a91b..7cd71518bed 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -996,13 +996,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
     pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
         for segment in segments {
             segment.with_generic_args(|generic_args| {
-                let mut err_for_lifetime = false;
-                let mut err_for_type = false;
+                let (mut err_for_lt, mut err_for_ty) = (false, false);
                 for arg in &generic_args.args {
                     let (mut span_err, span, kind) = match arg {
                         hir::GenericArg::Lifetime(lt) => {
-                            if err_for_lifetime { continue }
-                            err_for_lifetime = true;
+                            if err_for_lt { continue }
+                            err_for_lt = true;
                             (struct_span_err!(self.tcx().sess, lt.span, E0110,
                                             "lifetime parameters are not allowed on \
                                                 this type"),
@@ -1010,8 +1009,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                              "lifetime")
                         }
                         hir::GenericArg::Type(ty) => {
-                            if err_for_type { continue }
-                            err_for_type = true;
+                            if err_for_ty { continue }
+                            err_for_ty = true;
                             (struct_span_err!(self.tcx().sess, ty.span, E0109,
                                             "type parameters are not allowed on this type"),
                              ty.span,
@@ -1020,7 +1019,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                     };
                     span_err.span_label(span, format!("{} parameter not allowed", kind))
                             .emit();
-                    if err_for_lifetime && err_for_type {
+                    if err_for_lt && err_for_ty {
                         break;
                     }
                 }
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index f6b2ded176c..36ce01bcd08 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -329,46 +329,32 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
             if i < parent_substs.len() {
                 parent_substs[i]
             } else {
-                match param.kind {
-                    GenericParamDefKind::Lifetime => {
-                        if let Some(lifetime) = provided.as_ref().and_then(|data| {
-                            for arg in &data.args {
-                                match arg {
-                                    GenericArg::Lifetime(lt) => {
-                                        if i == parent_substs.len() {
-                                            return Some(lt);
-                                        }
-                                        i -= 1;
-                                    }
-                                    _ => {}
+                let (is_lt, is_ty) = match param.kind {
+                    GenericParamDefKind::Lifetime => (true, false),
+                    GenericParamDefKind::Type { .. } => (false, true),
+                };
+                provided.as_ref().and_then(|data| {
+                    for arg in &data.args {
+                        match arg {
+                            GenericArg::Lifetime(lt) if is_lt => {
+                                if i == parent_substs.len() {
+                                    return Some(AstConv::ast_region_to_region(
+                                        self.fcx, lt, Some(param)).into());
                                 }
+                                i -= 1;
                             }
-                            None
-                        }) {
-                            return AstConv::ast_region_to_region(
-                                self.fcx, lifetime, Some(param)).into();
-                        }
-                    }
-                    GenericParamDefKind::Type {..} => {
-                        if let Some(ast_ty) = provided.as_ref().and_then(|data| {
-                            for arg in &data.args {
-                                match arg {
-                                    GenericArg::Type(ty) => {
-                                        if i == parent_substs.len() + own_counts.lifetimes {
-                                            return Some(ty);
-                                        }
-                                        i -= 1;
-                                    }
-                                    _ => {}
+                            GenericArg::Lifetime(_) => {}
+                            GenericArg::Type(ty) if is_ty => {
+                                if i == parent_substs.len() + own_counts.lifetimes {
+                                    return Some(self.to_ty(ty).into());
                                 }
+                                i -= 1;
                             }
-                            None
-                        }) {
-                            return self.to_ty(ast_ty).into();
+                            GenericArg::Type(_) => {}
                         }
                     }
-                }
-                self.var_for_def(self.span, param)
+                    None
+                }).unwrap_or_else(|| self.var_for_def(self.span, param))
             }
         })
     }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 6ac9a0fdfc0..036c0aa442e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4977,8 +4977,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 s.args.as_ref().map_or(
                     (vec![], vec![], s.infer_types, &[][..]),
                     |data| {
-                        let mut lifetimes = vec![];
-                        let mut types = vec![];
+                        let (mut lifetimes, mut types) = (vec![], vec![]);
                         data.args.iter().for_each(|arg| match arg {
                             GenericArg::Lifetime(lt) => lifetimes.push(lt),
                             GenericArg::Type(ty) => types.push(ty),
@@ -4987,14 +4986,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     }
                 )
             });
-        let infer_lifetimes = lifetimes.len() == 0;
-
-        let count_lifetime_params = |n| {
-            format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
-        };
-        let count_type_params = |n| {
-            format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
-        };
 
         // Check provided parameters.
         let ((ty_required, ty_accepted), lt_accepted) =
@@ -5008,9 +4999,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 let mut ty_params = ParamRange { required: 0, accepted: 0 };
                 for param in &generics.params {
                     match param.kind {
-                        GenericParamDefKind::Lifetime => {
-                            lt_accepted += 1;
-                        }
+                        GenericParamDefKind::Lifetime => lt_accepted += 1,
                         GenericParamDefKind::Type { has_default, .. } => {
                             ty_params.accepted += 1;
                             if !has_default {
@@ -5027,36 +5016,37 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                 ((ty_params.required, ty_params.accepted), lt_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: \
-                              expected at most {}, found {}",
-                             expected_text, actual_text)
-                .span_label(span, format!("expected {}", expected_text))
-                .emit();
-
+        let count_type_params = |n| {
+            format!("{} type parameter{}", n, if n == 1 { "" } else { "s" })
+        };
+        let expected_text = count_type_params(ty_accepted);
+        let actual_text = count_type_params(types.len());
+        if let Some((mut err, span)) = if types.len() > ty_accepted {
             // To prevent derived errors to accumulate due to extra
             // type parameters, we force instantiate_value_path to
             // use inference variables instead of the provided types.
             *segment = None;
+            let span = types[ty_accepted].span;
+            Some((struct_span_err!(self.tcx.sess, span, E0087,
+                                  "too many type parameters provided: \
+                                  expected at most {}, found {}",
+                                  expected_text, actual_text), span))
         } 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: \
-                              expected {}, found {}",
-                             expected_text, actual_text)
-                .span_label(span, format!("expected {}", expected_text))
-                .emit();
+            Some((struct_span_err!(self.tcx.sess, span, E0089,
+                                  "too few type parameters provided: \
+                                  expected {}, found {}",
+                                  expected_text, actual_text), span))
+        } else {
+            None
+        } {
+            err.span_label(span, format!("expected {}", expected_text)).emit();
         }
 
         if !bindings.is_empty() {
             AstConv::prohibit_projection(self, bindings[0].span);
         }
 
+        let infer_lifetimes = lifetimes.len() == 0;
         // Prohibit explicit lifetime arguments if late bound lifetime parameters are present.
         let has_late_bound_lifetime_defs =
             segment.map_or(None, |(_, generics)| generics.has_late_bound_regions);
@@ -5080,25 +5070,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             return;
         }
 
-        if lifetimes.len() > lt_accepted {
+        let count_lifetime_params = |n| {
+            format!("{} lifetime parameter{}", n, if n == 1 { "" } else { "s" })
+        };
+        let expected_text = count_lifetime_params(lt_accepted);
+        let actual_text = count_lifetime_params(lifetimes.len());
+        if let Some((mut err, span)) = 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: \
-                              expected at most {}, found {}",
-                             expected_text, actual_text)
-                .span_label(span, format!("expected {}", expected_text))
-                .emit();
+            Some((struct_span_err!(self.tcx.sess, span, E0088,
+                                  "too many lifetime parameters provided: \
+                                  expected at most {}, found {}",
+                                  expected_text, actual_text), span))
         } 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: \
-                              expected {}, found {}",
-                             expected_text, actual_text)
-                .span_label(span, format!("expected {}", expected_text))
-                .emit();
+            Some((struct_span_err!(self.tcx.sess, span, E0090,
+                                  "too few lifetime parameters provided: \
+                                  expected {}, found {}",
+                                  expected_text, actual_text), span))
+        } else {
+            None
+        } {
+            err.span_label(span, format!("expected {}", expected_text)).emit();
         }
     }
 
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 05d390b8dae..f8f01262790 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -660,15 +660,12 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 fn reject_shadowing_parameters(tcx: TyCtxt, def_id: DefId) {
     let generics = tcx.generics_of(def_id);
     let parent = tcx.generics_of(generics.parent.unwrap());
-    let impl_params: FxHashMap<_, _> =
-        parent.params.iter()
-                     .flat_map(|param| match param.kind {
-                         GenericParamDefKind::Lifetime => None,
-                         GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
-                     })
-                     .collect();
-
-    for method_param in generics.params.iter() {
+    let impl_params: FxHashMap<_, _> = parent.params.iter().flat_map(|param| match param.kind {
+        GenericParamDefKind::Lifetime => None,
+        GenericParamDefKind::Type {..} => Some((param.name, param.def_id)),
+    }).collect();
+
+    for method_param in &generics.params {
         match method_param.kind {
             // Shadowing is checked in resolve_lifetime.
             GenericParamDefKind::Lifetime => continue,
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index 007ef4dee55..5a442881a63 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -35,13 +35,8 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
 
             Some(trait_ref) => {
                 let trait_def = self.tcx.trait_def(trait_ref.def_id);
-                let unsafe_attr = impl_generics.and_then(|g| {
-                    for param in &g.params {
-                        if param.pure_wrt_drop {
-                            return Some("may_dangle");
-                        }
-                    }
-                    None
+                let unsafe_attr = impl_generics.and_then(|generics| {
+                    generics.params.iter().find(|p| p.pure_wrt_drop).map(|_| "may_dangle")
                 });
                 match (trait_def.unsafety, unsafe_attr, unsafety, polarity) {
                     (Unsafety::Normal, None, Unsafety::Unsafe, hir::ImplPolarity::Positive) => {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 0a6edd8d0ce..2e4ceb5a65c 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -117,12 +117,11 @@ impl<'a, 'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'a, 'tcx> {
         for param in &generics.params {
             match param.kind {
                 hir::GenericParamKind::Lifetime { .. } => {}
-                hir::GenericParamKind::Type { ref default, .. } => {
-                    if default.is_some() {
-                        let def_id = self.tcx.hir.local_def_id(param.id);
-                        self.tcx.type_of(def_id);
-                    }
+                hir::GenericParamKind::Type { ref default, .. } if default.is_some() => {
+                    let def_id = self.tcx.hir.local_def_id(param.id);
+                    self.tcx.type_of(def_id);
                 }
+                hir::GenericParamKind::Type { .. } => {}
             }
         }
         intravisit::walk_generics(self, generics);
@@ -316,11 +315,8 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
         let from_ty_params =
             ast_generics.params.iter()
                 .filter_map(|param| match param.kind {
-                    GenericParamKind::Type { ref bounds, .. } => {
-                        if param.id == param_id {
-                            return Some(bounds);
-                        }
-                        None
+                    GenericParamKind::Type { ref bounds, .. } if param.id == param_id => {
+                        Some(bounds)
                     }
                     _ => None
                 })
@@ -1470,11 +1466,8 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                            .to_ty(tcx);
                 index += 1;
 
-                let bounds = compute_bounds(&icx,
-                                            param_ty,
-                                            bounds,
-                                            SizedByDefault::Yes,
-                                            param.span);
+                let bounds =
+                    compute_bounds(&icx, param_ty, bounds, SizedByDefault::Yes, param.span);
                 predicates.extend(bounds.predicates(tcx, param_ty));
             }
             _ => {}
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index da54eeabdb9..3f7e3529e96 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -1501,12 +1501,12 @@ struct Foo {
 "##,
 
 E0131: r##"
-It is not possible to define `main` with type parameters, or even with function
-parameters. When `main` is present, it must take no arguments and return `()`.
+It is not possible to define `main` with generic parameters.
+When `main` is present, it must take no arguments and return `()`.
 Erroneous code example:
 
 ```compile_fail,E0131
-fn main<T>() { // error: main function is not allowed to have type parameters
+fn main<T>() { // error: main function is not allowed to have generic parameters
 }
 ```
 "##,
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index fb005ba18e9..dcc5fa53d2f 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -191,16 +191,9 @@ fn check_main_fn_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         hir::ItemFn(.., ref generics, _) => {
                             let mut error = false;
                             if !generics.params.is_empty() {
-                                let param_type = if generics.is_lt_parameterized() {
-                                    "lifetime"
-                                } else {
-                                    "type"
-                                };
-                                let msg =
-                                    format!("`main` function is not allowed to have {} parameters",
-                                            param_type);
-                                let label =
-                                    format!("`main` cannot have {} parameters", param_type);
+                                let msg = format!("`main` function is not allowed to have generic \
+                                                   parameters");
+                                let label = format!("`main` cannot have generic parameters");
                                 struct_span_err!(tcx.sess, generics.span, E0131, "{}", msg)
                                     .span_label(generics.span, label)
                                     .emit();
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 3a4e582622f..89835ab6aae 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -3540,27 +3540,23 @@ impl Clean<GenericArgs> for hir::GenericArgs {
                 output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
             }
         } else {
-            let mut lifetimes = vec![];
-            let mut types = vec![];
+            let (mut lifetimes, mut types) = (vec![], vec![]);
             let mut elided_lifetimes = true;
             for arg in &self.args {
                 match arg {
-                    GenericArg::Lifetime(lt) if elided_lifetimes => {
-                        if lt.is_elided() {
+                    GenericArg::Lifetime(lt) => {
+                        if !lt.is_elided() {
                             elided_lifetimes = false;
-                            lifetimes = vec![];
-                            continue;
                         }
                         lifetimes.push(lt.clean(cx));
                     }
-                    GenericArg::Lifetime(_) => {}
                     GenericArg::Type(ty) => {
                         types.push(ty.clean(cx));
                     }
                 }
             }
             GenericArgs::AngleBracketed {
-                lifetimes,
+                lifetimes: if elided_lifetimes { vec![] } else { lifetimes },
                 types,
                 bindings: self.bindings.clean(cx),
             }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index b647dc7923e..e12369a522d 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -136,7 +136,7 @@ pub trait Visitor<'ast>: Sized {
     fn visit_generic_arg(&mut self, generic_arg: &'ast GenericArg) {
         match generic_arg {
             GenericArg::Lifetime(lt) => self.visit_lifetime(lt),
-            GenericArg::Type(ty)     => self.visit_ty(ty),
+            GenericArg::Type(ty) => self.visit_ty(ty),
         }
     }
     fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) {
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 6c9aea51c7c..1024d445cdb 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -665,35 +665,18 @@ impl<'a> TraitDef<'a> {
         // Create the reference to the trait.
         let trait_ref = cx.trait_ref(trait_path);
 
-        // Create the type parameters on the `self` path.
-        let self_ty_params: Vec<P<ast::Ty>> = generics.params
-            .iter()
-            .filter_map(|param| match param.kind {
-                GenericParamKind::Type { .. } => Some(cx.ty_ident(self.span, param.ident)),
-                _ => None,
-            })
-            .collect();
-
-        let self_lifetimes: Vec<ast::Lifetime> = generics.params
-            .iter()
-            .filter_map(|param| match param.kind {
-                GenericParamKind::Lifetime { ref lifetime, .. } => Some(*lifetime),
-                _ => None,
-            })
-            .collect();
-
-        let self_params = self_lifetimes.into_iter()
-                                        .map(|lt| GenericArg::Lifetime(lt))
-                                        .chain(self_ty_params.into_iter().map(|ty|
-                                            GenericArg::Type(ty)))
-                                        .collect();
+        let self_params: Vec<_> = generics.params.iter().map(|param| match param.kind {
+            GenericParamKind::Lifetime { ref lifetime, .. } => {
+                GenericArg::Lifetime(*lifetime)
+            }
+            GenericParamKind::Type { .. } => {
+                GenericArg::Type(cx.ty_ident(self.span, param.ident))
+            }
+        }).collect();
 
         // Create the type of `self`.
-        let self_type = cx.ty_path(cx.path_all(self.span,
-                                               false,
-                                               vec![type_ident],
-                                               self_params,
-                                               Vec::new()));
+        let path = cx.path_all(self.span, false, vec![type_ident], self_params, vec![]);
+        let self_type = cx.ty_path(path);
 
         let attr = cx.attribute(self.span,
                                 cx.meta_word(self.span,
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 78f6a9b9137..127ed62b8c5 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -185,41 +185,22 @@ impl<'a> Ty<'a> {
                    cx: &ExtCtxt,
                    span: Span,
                    self_ty: Ident,
-                   self_generics: &Generics)
+                   generics: &Generics)
                    -> ast::Path {
         match *self {
             Self_ => {
-                let ty_params: Vec<P<ast::Ty>> = self_generics.params
-                    .iter()
-                    .filter_map(|param| match param.kind {
-                        GenericParamKind::Type { .. } => {
-                            Some(cx.ty_ident(span, param.ident))
-                        }
-                        _ => None,
-                    })
-                    .collect();
-
-                let lifetimes: Vec<ast::Lifetime> = self_generics.params
-                    .iter()
-                    .filter_map(|param| match param.kind {
-                        GenericParamKind::Lifetime { ref lifetime, .. } => Some(*lifetime),
-                        _ => None,
-                    })
-                    .collect();
-
-                let params = lifetimes.into_iter()
-                                      .map(|lt| GenericArg::Lifetime(lt))
-                                      .chain(ty_params.into_iter().map(|ty|
-                                            GenericArg::Type(ty)))
-                                      .collect();
+                let params: Vec<_> = generics.params.iter().map(|param| match param.kind {
+                    GenericParamKind::Lifetime { ref lifetime, .. } => {
+                        GenericArg::Lifetime(*lifetime)
+                    }
+                    GenericParamKind::Type { .. } => {
+                        GenericArg::Type(cx.ty_ident(span, param.ident))
+                    }
+                }).collect();
 
-                cx.path_all(span,
-                            false,
-                            vec![self_ty],
-                            params,
-                            Vec::new())
+                cx.path_all(span, false, vec![self_ty], params, vec![])
             }
-            Literal(ref p) => p.to_path(cx, span, self_ty, self_generics),
+            Literal(ref p) => p.to_path(cx, span, self_ty, generics),
             Ptr(..) => cx.span_bug(span, "pointer in a path in generic `derive`"),
             Tuple(..) => cx.span_bug(span, "tuple in a path in generic `derive`"),
         }
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 5c3080260cc..bbc5b03d688 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -43,7 +43,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt,
                                                      cx.ty_ident(sp, Ident::from_str("str")),
                                                      Some(lt),
                                                      ast::Mutability::Immutable))],
-                                     Vec::new()))
+                                     vec![]))
         }
         Ok(s) => {
             cx.expr_call_global(sp,
diff --git a/src/test/compile-fail/issue-1900.rs b/src/test/compile-fail/issue-1900.rs
index c7564a9355b..ccdd9db25c4 100644
--- a/src/test/compile-fail/issue-1900.rs
+++ b/src/test/compile-fail/issue-1900.rs
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// error-pattern: `main` function is not allowed to have type parameters
+// error-pattern: `main` function is not allowed to have generic parameters
 fn main<T>() { }
diff --git a/src/test/ui/error-codes/E0131.stderr b/src/test/ui/error-codes/E0131.stderr
index ba9355763f6..46bc872746c 100644
--- a/src/test/ui/error-codes/E0131.stderr
+++ b/src/test/ui/error-codes/E0131.stderr
@@ -1,8 +1,8 @@
-error[E0131]: `main` function is not allowed to have type parameters
+error[E0131]: `main` function is not allowed to have generic parameters
   --> $DIR/E0131.rs:11:8
    |
 LL | fn main<T>() {
-   |        ^^^ `main` cannot have type parameters
+   |        ^^^ `main` cannot have generic parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-51022.rs b/src/test/ui/issue-51022.rs
index f9486fa57b1..831c3e5fda0 100644
--- a/src/test/ui/issue-51022.rs
+++ b/src/test/ui/issue-51022.rs
@@ -9,4 +9,4 @@
 // except according to those terms.
 
 fn main<'a>() { }
-    //~^ ERROR `main` function is not allowed to have lifetime parameters [E0131]
+    //~^ ERROR `main` function is not allowed to have generic parameters [E0131]
diff --git a/src/test/ui/issue-51022.stderr b/src/test/ui/issue-51022.stderr
index 3b691bbb033..1daa8dfbba6 100644
--- a/src/test/ui/issue-51022.stderr
+++ b/src/test/ui/issue-51022.stderr
@@ -1,8 +1,8 @@
-error[E0131]: `main` function is not allowed to have lifetime parameters
+error[E0131]: `main` function is not allowed to have generic parameters
   --> $DIR/issue-51022.rs:11:8
    |
 LL | fn main<'a>() { }
-   |        ^^^^ `main` cannot have lifetime parameters
+   |        ^^^^ `main` cannot have generic parameters
 
 error: aborting due to previous error