diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index eacad100f10be..3a1b0b8c58ebb 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -602,9 +602,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) {
             walk_list!(visitor, visit_ty_param_bound, bounds);
             walk_list!(visitor, visit_lifetime, lifetimes);
         }
-        TyImplTraitUniversal(_, ref bounds) => {
-            walk_list!(visitor, visit_ty_param_bound, bounds);
-        }
         TyTypeof(expression) => {
             visitor.visit_nested_body(expression)
         }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index b544ea820c0f7..847cf64ce6a03 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -61,6 +61,7 @@ use syntax::attr;
 use syntax::ast::*;
 use syntax::errors;
 use syntax::ext::hygiene::{Mark, SyntaxContext};
+use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::codemap::{self, respan, Spanned, CompilerDesugaringKind};
 use syntax::std_inject;
@@ -106,6 +107,13 @@ pub struct LoweringContext<'a> {
     is_in_loop_condition: bool,
     is_in_trait_impl: bool,
 
+    // This is a list of in-band type definitions being generated by
+    // Argument-position `impl Trait`.
+    // When traversing a signature such as `fn foo(x: impl Trait)`,
+    // we record `impl Trait` as a new type parameter, then later
+    // add it on to `foo`s generics.
+    in_band_ty_params: Vec<hir::TyParam>,
+
     // Used to create lifetime definitions from in-band lifetime usages.
     // e.g. `fn foo(x: &'x u8) -> &'x u8` to `fn foo<'x>(x: &'x u8) -> &'x u8`
     // When a named lifetime is encountered in a function or impl header and
@@ -197,6 +205,7 @@ pub fn lower_crate(sess: &Session,
         node_id_to_hir_id: IndexVec::new(),
         is_generator: false,
         is_in_trait_impl: false,
+        in_band_ty_params: Vec::new(),
         lifetimes_to_define: Vec::new(),
         is_collecting_in_band_lifetimes: false,
         in_scope_lifetimes: Vec::new(),
@@ -526,20 +535,23 @@ impl<'a> LoweringContext<'a> {
     // Creates a new hir::LifetimeDef for every new lifetime encountered
     // while evaluating `f`. Definitions are created with the parent provided.
     // If no `parent_id` is provided, no definitions will be returned.
-    fn collect_in_band_lifetime_defs<T, F>(
+    fn collect_in_band_defs<T, F>(
         &mut self,
         parent_id: Option<DefId>,
         f: F
-    ) -> (Vec<hir::LifetimeDef>, T) where F: FnOnce(&mut LoweringContext) -> T
+    ) -> (Vec<hir::TyParam>, Vec<hir::LifetimeDef>, T) where F: FnOnce(&mut LoweringContext) -> T
     {
         assert!(!self.is_collecting_in_band_lifetimes);
         assert!(self.lifetimes_to_define.is_empty());
         self.is_collecting_in_band_lifetimes = self.sess.features.borrow().in_band_lifetimes;
 
+        assert!(self.in_band_ty_params.is_empty());
+
         let res = f(self);
 
         self.is_collecting_in_band_lifetimes = false;
 
+        let in_band_ty_params = self.in_band_ty_params.split_off(0);
         let lifetimes_to_define = self.lifetimes_to_define.split_off(0);
 
         let lifetime_defs = match parent_id {
@@ -569,7 +581,7 @@ impl<'a> LoweringContext<'a> {
             None => Vec::new(),
         };
 
-        (lifetime_defs, res)
+        (in_band_ty_params, lifetime_defs, res)
     }
 
     // Evaluates `f` with the lifetimes in `lt_defs` in-scope.
@@ -613,11 +625,9 @@ impl<'a> LoweringContext<'a> {
         res
     }
 
-    // Appends in-band lifetime defs to the existing set of out-of-band lifetime defs.
-    // Evaluates all within the context of the out-of-band defs.
-    // If provided, `impl_item_id` is used to find the parent impls of impl items so
-    // that their generics are not duplicated.
-    fn add_in_band_lifetime_defs<F, T>(
+    // Appends in-band lifetime defs and argument-position `impl Trait` defs
+    // to the existing set of generics.
+    fn add_in_band_defs<F, T>(
         &mut self,
         generics: &Generics,
         parent_id: Option<DefId>,
@@ -625,17 +635,23 @@ impl<'a> LoweringContext<'a> {
     ) -> (hir::Generics, T)
         where F: FnOnce(&mut LoweringContext) -> T
     {
-        let (in_band_defs, (mut lowered_generics, res)) =
+        let (in_band_ty_defs, in_band_lifetime_defs, (mut lowered_generics, res)) =
             self.with_in_scope_lifetime_defs(&generics.lifetimes, |this| {
-                this.collect_in_band_lifetime_defs(parent_id, |this| {
+                this.collect_in_band_defs(parent_id, |this| {
                     (this.lower_generics(generics), f(this))
                 })
             });
 
+        lowered_generics.ty_params =
+            lowered_generics.ty_params
+                .iter().cloned()
+                .chain(in_band_ty_defs.into_iter())
+                .collect();
+
         lowered_generics.lifetimes =
             lowered_generics.lifetimes
                 .iter().cloned()
-               .chain(in_band_defs.into_iter())
+               .chain(in_band_lifetime_defs.into_iter())
                .collect();
 
         (lowered_generics, res)
@@ -922,6 +938,7 @@ impl<'a> LoweringContext<'a> {
             }
             TyKind::ImplTrait(ref bounds) => {
                 use syntax::feature_gate::{emit_feature_err, GateIssue};
+                let span = t.span;
                 match itctx {
                     ImplTraitContext::Existential => {
                         let has_feature = self.sess.features.borrow().conservative_impl_trait;
@@ -944,7 +961,7 @@ impl<'a> LoweringContext<'a> {
                                     id: self.next_id().node_id,
                                     predicates: Vec::new().into(),
                                 },
-                                span: t.span,
+                                span,
                             },
                             bounds: hir_bounds,
                         }, lifetimes)
@@ -956,7 +973,35 @@ impl<'a> LoweringContext<'a> {
                                              t.span, GateIssue::Language,
                                              "`impl Trait` in argument position is experimental");
                         }
-                        hir::TyImplTraitUniversal(def_id, self.lower_bounds(bounds, itctx))
+
+                        let def_node_id = self.next_id().node_id;
+
+                        // Add a definition for the in-band TyParam
+                        let def_index = self.resolver.definitions().create_def_with_parent(
+                            def_id.index,
+                            def_node_id,
+                            DefPathData::ImplTrait,
+                            DefIndexAddressSpace::High,
+                            Mark::root()
+                        );
+
+                        let hir_bounds = self.lower_bounds(bounds, itctx);
+                        self.in_band_ty_params.push(hir::TyParam {
+                            // Set the name to `impl Bound1 + Bound2`
+                            name: Symbol::intern(&pprust::ty_to_string(t)),
+                            id: def_node_id,
+                            bounds: hir_bounds,
+                            default: None,
+                            span,
+                            pure_wrt_drop: false,
+                            synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
+                        });
+
+                        hir::TyPath(hir::QPath::Resolved(None, P(hir::Path {
+                            span,
+                            def: Def::TyParam(DefId::local(def_index)),
+                            segments: vec![].into(),
+                        })))
                     },
                     ImplTraitContext::Disallowed => {
                         span_err!(self.sess, t.span, E0562,
@@ -1829,7 +1874,7 @@ impl<'a> LoweringContext<'a> {
                         this.expr_block(body, ThinVec::new())
                     });
                     let (generics, fn_decl) =
-                        this.add_in_band_lifetime_defs(generics, fn_def_id, |this|
+                        this.add_in_band_defs(generics, fn_def_id, |this|
                             this.lower_fn_decl(decl, fn_def_id, true));
 
                     hir::ItemFn(fn_decl,
@@ -1883,7 +1928,7 @@ impl<'a> LoweringContext<'a> {
                            ref impl_items) => {
                 let def_id = self.resolver.definitions().opt_local_def_id(id);
                 let (generics, (ifce, lowered_ty)) =
-                    self.add_in_band_lifetime_defs(ast_generics, def_id, |this| {
+                    self.add_in_band_defs(ast_generics, def_id, |this| {
                         let ifce = ifce.as_ref().map(|trait_ref| {
                             this.lower_trait_ref(trait_ref, ImplTraitContext::Disallowed)
                         });
@@ -2059,7 +2104,7 @@ impl<'a> LoweringContext<'a> {
                 }
                 TraitItemKind::Method(ref sig, None) => {
                     let names = this.lower_fn_args_to_names(&sig.decl);
-                    this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this|
+                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
                         hir::TraitItemKind::Method(
                             this.lower_method_sig(sig, fn_def_id, false),
                             hir::TraitMethod::Required(names)))
@@ -2070,7 +2115,7 @@ impl<'a> LoweringContext<'a> {
                         this.expr_block(body, ThinVec::new())
                     });
 
-                    this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this|
+                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
                         hir::TraitItemKind::Method(
                             this.lower_method_sig(sig, fn_def_id, false),
                            hir::TraitMethod::Provided(body_id)))
@@ -2147,7 +2192,7 @@ impl<'a> LoweringContext<'a> {
                     });
                     let impl_trait_return_allow = !this.is_in_trait_impl;
 
-                    this.add_in_band_lifetime_defs(&i.generics, fn_def_id, |this|
+                    this.add_in_band_defs(&i.generics, fn_def_id, |this|
                         hir::ImplItemKind::Method(
                             this.lower_method_sig(sig, fn_def_id, impl_trait_return_allow),
                             body_id))
@@ -2280,7 +2325,7 @@ impl<'a> LoweringContext<'a> {
                     ForeignItemKind::Fn(ref fdec, ref generics) => {
                         // Disallow impl Trait in foreign items
                         let (generics, (fn_dec, fn_args)) =
-                            this.add_in_band_lifetime_defs(
+                            this.add_in_band_defs(
                                 generics,
                                 Some(def_id),
                                 |this| (
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index dc44a943e4cf8..f8da8145b0d59 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -1506,7 +1506,7 @@ pub enum Ty_ {
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
     TyTraitObject(HirVec<PolyTraitRef>, Lifetime),
-    /// An exsitentially quantified (there exists a type satisfying) `impl
+    /// An existentially quantified (there exists a type satisfying) `impl
     /// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
     ///
     /// The `ExistTy` structure emulates an
@@ -1518,9 +1518,6 @@ pub enum Ty_ {
     /// because all in-scope type parameters are captured by `impl Trait`,
     /// so they are resolved directly through the parent `Generics`.
     TyImplTraitExistential(ExistTy, HirVec<Lifetime>),
-    /// An universally quantified (for all types satisfying) `impl
-    /// Bound1 + Bound2 + Bound3` type where `Bound` is a trait or a lifetime.
-    TyImplTraitUniversal(DefId, TyParamBounds),
     /// Unused for now
     TyTypeof(BodyId),
     /// TyInfer means the type should be inferred instead of it having been
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index c7bb121e90105..21e2b8233dcbe 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -424,9 +424,6 @@ impl<'a> State<'a> {
             hir::TyImplTraitExistential(ref existty, ref _lifetimes) => {
                 self.print_bounds("impl", &existty.bounds[..])?;
             }
-            hir::TyImplTraitUniversal(_, ref bounds) => {
-                self.print_bounds("impl", &bounds[..])?;
-            }
             hir::TyArray(ref ty, v) => {
                 self.s.word("[")?;
                 self.print_type(&ty)?;
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index ff5327ced8b79..02a394f9634c2 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -312,7 +312,6 @@ impl_stable_hash_for!(enum hir::Ty_ {
     TyPath(qpath),
     TyTraitObject(trait_refs, lifetime),
     TyImplTraitExistential(existty, lifetimes),
-    TyImplTraitUniversal(def_id, bounds),
     TyTypeof(body_id),
     TyErr,
     TyInfer
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 188dbe2f1de51..93e850267b658 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -2146,19 +2146,6 @@ fn insert_late_bound_lifetimes(
         visit_where_predicate,
         &generics.where_clause.predicates
     );
-    // We need to collect argument impl Trait lifetimes as well,
-    // we do so here.
-    walk_list!(
-        &mut appears_in_where_clause,
-        visit_ty,
-        decl.inputs
-            .iter()
-            .filter(|ty| if let hir::TyImplTraitUniversal(..) = ty.node {
-                true
-            } else {
-                false
-            })
-    );
     for lifetime_def in &generics.lifetimes {
         if !lifetime_def.bounds.is_empty() {
             // `'a: 'b` means both `'a` and `'b` are referenced
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 6b37a30cb82d8..34c539795a181 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -30,7 +30,6 @@ use util::nodemap::FxHashSet;
 
 use std::iter;
 use syntax::{abi, ast};
-use syntax::symbol::Symbol;
 use syntax::feature_gate::{GateIssue, emit_feature_err};
 use syntax_pos::Span;
 
@@ -1050,13 +1049,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                 let def_id = tcx.hir.local_def_id(ast_ty.id);
                 self.impl_trait_ty_to_ty(def_id, lifetimes)
             }
-            hir::TyImplTraitUniversal(fn_def_id, _) => {
-                let impl_trait_def_id = tcx.hir.local_def_id(ast_ty.id);
-                let generics = tcx.generics_of(fn_def_id);
-                let index = generics.type_param_to_index[&impl_trait_def_id.index];
-                tcx.mk_param(index,
-                             Symbol::intern(&tcx.hir.node_to_pretty_string(ast_ty.id)))
-            }
             hir::TyPath(hir::QPath::Resolved(ref maybe_qself, ref path)) => {
                 debug!("ast_ty_to_ty: maybe_qself={:?} path={:?}", maybe_qself, path);
                 let opt_self_ty = maybe_qself.as_ref().map(|qself| {
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 3d4d8e65f699d..f51bdf050c715 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -43,7 +43,6 @@ use rustc_const_math::ConstInt;
 use std::collections::BTreeMap;
 
 use syntax::{abi, ast};
-use syntax::ptr::P;
 use syntax::codemap::Spanned;
 use syntax::symbol::{Symbol, keywords};
 use syntax_pos::{Span, DUMMY_SP};
@@ -880,32 +879,22 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let mut allow_defaults = false;
 
     let no_generics = hir::Generics::empty();
-    let (ast_generics, opt_inputs) = match node {
-        NodeTraitItem(item) => {
-            match item.node {
-                TraitItemKind::Method(ref sig, _) => (&item.generics, Some(&sig.decl.inputs)),
-                _ => (&item.generics, None)
-            }
-        }
+    let ast_generics = match node {
+        NodeTraitItem(item) => &item.generics,
 
-        NodeImplItem(item) => {
-            match item.node {
-                ImplItemKind::Method(ref sig, _) => (&item.generics, Some(&sig.decl.inputs)),
-                _ => (&item.generics, None)
-            }
-        }
+        NodeImplItem(item) => &item.generics,
 
         NodeItem(item) => {
             match item.node {
-                ItemFn(ref decl, .., ref generics, _) => (generics, Some(&decl.inputs)),
-                ItemImpl(_, _, _, ref generics, ..) => (generics, None),
+                ItemFn(.., ref generics, _) |
+                ItemImpl(_, _, _, ref generics, ..) => generics,
 
                 ItemTy(_, ref generics) |
                 ItemEnum(_, ref generics) |
                 ItemStruct(_, ref generics) |
                 ItemUnion(_, ref generics) => {
                     allow_defaults = true;
-                    (generics, None)
+                    generics
                 }
 
                 ItemTrait(_, _, ref generics, ..) | ItemTraitAlias(ref generics, ..) => {
@@ -926,26 +915,26 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     });
 
                     allow_defaults = true;
-                    (generics, None)
+                    generics
                 }
 
-                _ => (&no_generics, None)
+                _ => &no_generics,
             }
         }
 
         NodeForeignItem(item) => {
             match item.node {
-                ForeignItemStatic(..) => (&no_generics, None),
-                ForeignItemFn(ref decl, _, ref generics) => (generics, Some(&decl.inputs)),
-                ForeignItemType => (&no_generics, None)
+                ForeignItemStatic(..) => &no_generics,
+                ForeignItemFn(_, _, ref generics) => generics,
+                ForeignItemType => &no_generics,
             }
         }
 
         NodeTy(&hir::Ty { node: hir::TyImplTraitExistential(ref exist_ty, _), .. }) => {
-            (&exist_ty.generics, None)
+            &exist_ty.generics
         }
 
-        _ => (&no_generics, None)
+        _ => &no_generics,
     };
 
     let has_self = opt_self.is_some();
@@ -1003,23 +992,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
     });
 
-    let fn_ins = opt_inputs.map(|tys| &tys[..]);
-    let univ_impl_trait_info = extract_universal_impl_trait_info(tcx, fn_ins);
-    let other_type_start = type_start + ast_generics.ty_params.len() as u32;
-    let mut types: Vec<_> = opt_self.into_iter()
-        .chain(types)
-        .chain(univ_impl_trait_info.iter().enumerate().map(|(i, info)| {
-            ty::TypeParameterDef {
-                index: other_type_start + i as u32,
-                name: Symbol::intern(&tcx.hir.node_to_pretty_string(info.id)),
-                def_id: info.def_id,
-                has_default: false,
-                object_lifetime_default: rl::Set1::Empty,
-                pure_wrt_drop: false,
-                synthetic: Some(SyntheticTyParamKind::ImplTrait),
-            }
-        }))
-        .collect();
+    let mut types: Vec<_> = opt_self.into_iter().chain(types).collect();
 
     // provide junk type parameter defs - the only place that
     // cares about anything but the length is instantiation,
@@ -1419,50 +1392,36 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     let icx = ItemCtxt::new(tcx, def_id);
     let no_generics = hir::Generics::empty();
-    let (ast_generics, opt_inputs) = match node {
-        NodeTraitItem(item) => {
-            match item.node {
-                TraitItemKind::Method(ref sig, _) => (&item.generics, Some(&sig.decl.inputs)),
-                _ => (&item.generics, None)
-            }
-        }
-
-        NodeImplItem(item) => {
-            match item.node {
-                ImplItemKind::Method(ref sig, _) => (&item.generics, Some(&sig.decl.inputs)),
-                _ => (&item.generics, None)
-            }
-        }
+    let ast_generics = match node {
+        NodeTraitItem(item) => &item.generics,
+        NodeImplItem(item) => &item.generics,
 
         NodeItem(item) => {
             match item.node {
-                ItemFn(ref decl, .., ref generics, _) => (generics, Some(&decl.inputs)),
-
+                ItemFn(.., ref generics, _) |
                 ItemImpl(_, _, _, ref generics, ..) |
                 ItemTy(_, ref generics) |
                 ItemEnum(_, ref generics) |
                 ItemStruct(_, ref generics) |
-                ItemUnion(_, ref generics) => {
-                    (generics, None)
-                }
+                ItemUnion(_, ref generics) => generics,
 
                 ItemTrait(_, _, ref generics, .., ref items) => {
                     is_trait = Some((ty::TraitRef {
                         def_id,
                         substs: Substs::identity_for_item(tcx, def_id)
                     }, items));
-                    (generics, None)
+                    generics
                 }
 
-                _ => (&no_generics, None)
+                _ => &no_generics,
             }
         }
 
         NodeForeignItem(item) => {
             match item.node {
-                ForeignItemStatic(..) => (&no_generics, None),
-                ForeignItemFn(ref decl, _, ref generics) => (generics, Some(&decl.inputs)),
-                ForeignItemType => (&no_generics, None),
+                ForeignItemStatic(..) => &no_generics,
+                ForeignItemFn(_, _, ref generics) => generics,
+                ForeignItemType => &no_generics,
             }
         }
 
@@ -1491,7 +1450,7 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             };
         }
 
-        _ => (&no_generics, None)
+        _ => &no_generics,
     };
 
     let generics = tcx.generics_of(def_id);
@@ -1622,19 +1581,6 @@ fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }))
     }
 
-    // Add predicates from impl Trait arguments
-    let fn_ins = opt_inputs.map(|tys| &tys[..]);
-    let univ_impl_trait_info = extract_universal_impl_trait_info(tcx, fn_ins);
-    for info in univ_impl_trait_info.iter() {
-        let name = keywords::Invalid.name();
-        let param_ty = ty::ParamTy::new(index, name).to_ty(tcx);
-        index += 1;
-        let bounds = compute_bounds(&icx, param_ty, info.bounds,
-                                    SizedByDefault::Yes,
-                                    info.span);
-        predicates.extend(bounds.predicates(tcx, param_ty));
-    }
-
     // Subtle: before we store the predicates into the tcx, we
     // sort them so that predicates like `T: Foo<Item=U>` come
     // before uses of `U`.  This avoids false ambiguity errors
@@ -1795,54 +1741,3 @@ fn is_auto_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         _ => bug!("is_auto_impl applied to non-local def-id {:?}", def_id)
     }
 }
-
-struct ImplTraitUniversalInfo<'hir> {
-    id: ast::NodeId,
-    def_id: DefId,
-    span: Span,
-    bounds: &'hir [hir::TyParamBound],
-}
-
-/// Take some possible list of arguments and return the DefIds of the ImplTraitUniversal
-/// arguments
-fn extract_universal_impl_trait_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                               opt_inputs: Option<&'tcx [P<hir::Ty>]>)
-                                               -> Vec<ImplTraitUniversalInfo<'tcx>>
-{
-    // A visitor for simply collecting Universally quantified impl Trait arguments
-    struct ImplTraitUniversalVisitor<'tcx> {
-        items: Vec<&'tcx hir::Ty>
-    }
-
-    impl<'tcx> Visitor<'tcx> for ImplTraitUniversalVisitor<'tcx> {
-        fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
-            NestedVisitorMap::None
-        }
-
-        fn visit_ty(&mut self, ty: &'tcx hir::Ty) {
-            if let hir::TyImplTraitUniversal(..) = ty.node {
-                self.items.push(ty);
-            }
-            intravisit::walk_ty(self, ty);
-        }
-    }
-
-    let mut visitor = ImplTraitUniversalVisitor { items: Vec::new() };
-
-    if let Some(inputs) = opt_inputs {
-        for t in inputs.iter() {
-            visitor.visit_ty(t);
-        }
-    }
-
-    visitor.items.into_iter().map(|ty| if let hir::TyImplTraitUniversal(_, ref bounds) = ty.node {
-        ImplTraitUniversalInfo {
-            id: ty.id,
-            def_id: tcx.hir.local_def_id(ty.id),
-            span: ty.span,
-            bounds: bounds
-        }
-    } else {
-        span_bug!(ty.span, "this type should be a universally quantified impl trait. this is a bug")
-    }).collect()
-}
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 91908de98a65d..5f5ad952cf0c6 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2133,7 +2133,6 @@ impl Clean<Type> for hir::Ty {
             }
             TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
             TyImplTraitExistential(ref exist_ty, ref _lts) => ImplTrait(exist_ty.bounds.clean(cx)),
-            TyImplTraitUniversal(_, ref bounds) => ImplTrait(bounds.clean(cx)),
             TyInfer | TyErr => Infer,
             TyTypeof(..) => panic!("Unimplemented type {:?}", self.node),
         }
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index e9386e5187ff0..2b8bd58c51a53 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -1070,7 +1070,7 @@ impl<'a> State<'a> {
                 self.print_bounds(prefix, &bounds[..])?;
             }
             ast::TyKind::ImplTrait(ref bounds) => {
-                self.print_bounds("impl ", &bounds[..])?;
+                self.print_bounds("impl", &bounds[..])?;
             }
             ast::TyKind::Array(ref ty, ref v) => {
                 self.s.word("[")?;
diff --git a/src/test/run-pass/impl-trait/lifetimes.rs b/src/test/run-pass/impl-trait/lifetimes.rs
index 0f2f67fd89a12..a56f083e08f2f 100644
--- a/src/test/run-pass/impl-trait/lifetimes.rs
+++ b/src/test/run-pass/impl-trait/lifetimes.rs
@@ -57,9 +57,8 @@ fn pass_through_elision_with_fn_path<T: Fn(&u32) -> &u32>(
     x: &T
 ) -> impl Into<&impl Fn(&u32) -> &u32> { x }
 
-// FIXME(cramertj) Currently ICEing, part of issue #46685:
-// fn foo(x: &impl Debug) -> impl Into<&impl Debug> { x }
-// Works:
+fn foo(x: &impl Debug) -> impl Into<&impl Debug> { x }
+fn foo_explicit_lifetime<'a>(x: &'a impl Debug) -> impl Into<&'a impl Debug> { x }
 fn foo_no_outer_impl(x: &impl Debug) -> &impl Debug { x }
 fn foo_explicit_arg<T: Debug>(x: &T) -> impl Into<&impl Debug> { x }