about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-07-11 12:57:05 -0700
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2017-07-28 15:46:26 +0200
commit09a5d319ab8fbfd43530289bfff3899f9035e37f (patch)
tree663406df0155f3a95cbdc573aefb7b7cc7b5c5e5 /src
parent93172045c817ffa998d5e28a0899f33edf889f62 (diff)
downloadrust-09a5d319ab8fbfd43530289bfff3899f9035e37f.tar.gz
rust-09a5d319ab8fbfd43530289bfff3899f9035e37f.zip
Remove support for `gen arg`
Diffstat (limited to 'src')
-rw-r--r--src/doc/unstable-book/src/language-features/generators.md18
-rw-r--r--src/liballoc/boxed.rs8
-rw-r--r--src/libcore/ops/generator.rs16
-rw-r--r--src/librustc/cfg/construct.rs1
-rw-r--r--src/librustc/hir/intravisit.rs6
-rw-r--r--src/librustc/hir/lowering.rs36
-rw-r--r--src/librustc/hir/map/collector.rs7
-rw-r--r--src/librustc/hir/map/mod.rs11
-rw-r--r--src/librustc/hir/mod.rs24
-rw-r--r--src/librustc/hir/print.rs4
-rw-r--r--src/librustc/ich/impls_hir.rs17
-rw-r--r--src/librustc/ich/impls_ty.rs1
-rw-r--r--src/librustc/infer/error_reporting/need_type_info.rs13
-rw-r--r--src/librustc/infer/mod.rs19
-rw-r--r--src/librustc/middle/expr_use_visitor.rs2
-rw-r--r--src/librustc/middle/liveness.rs22
-rw-r--r--src/librustc/middle/mem_categorization.rs11
-rw-r--r--src/librustc/middle/region.rs3
-rw-r--r--src/librustc/mir/mod.rs4
-rw-r--r--src/librustc/traits/util.rs2
-rw-r--r--src/librustc/ty/mod.rs2
-rw-r--r--src/librustc/ty/structural_impls.rs7
-rw-r--r--src/librustc/ty/sty.rs1
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/mod.rs16
-rw-r--r--src/librustc_borrowck/diagnostics.rs1
-rw-r--r--src/librustc_mir/build/expr/as_lvalue.rs3
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs6
-rw-r--r--src/librustc_mir/build/expr/as_temp.rs2
-rw-r--r--src/librustc_mir/build/expr/category.rs1
-rw-r--r--src/librustc_mir/build/expr/into.rs1
-rw-r--r--src/librustc_mir/build/matches/mod.rs2
-rw-r--r--src/librustc_mir/build/mod.rs48
-rw-r--r--src/librustc_mir/build/scope.rs33
-rw-r--r--src/librustc_mir/dataflow/drop_flag_effects.rs5
-rw-r--r--src/librustc_mir/dataflow/move_paths/mod.rs1
-rw-r--r--src/librustc_mir/hair/cx/expr.rs3
-rw-r--r--src/librustc_mir/hair/mod.rs1
-rw-r--r--src/librustc_mir/transform/elaborate_drops.rs4
-rw-r--r--src/librustc_mir/transform/generator.rs51
-rw-r--r--src/librustc_passes/consts.rs1
-rw-r--r--src/librustc_trans/common.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs44
-rw-r--r--src/librustc_typeck/check/upvar.rs3
-rw-r--r--src/librustc_typeck/check/writeback.rs4
-rw-r--r--src/librustc_typeck/collect.rs2
-rw-r--r--src/librustc_typeck/diagnostics.rs3
-rw-r--r--src/libsyntax/ast.rs3
-rw-r--r--src/libsyntax/feature_gate.rs5
-rw-r--r--src/libsyntax/fold.rs1
-rw-r--r--src/libsyntax/parse/parser.rs14
-rw-r--r--src/libsyntax/print/pprust.rs3
-rw-r--r--src/libsyntax/visit.rs1
-rw-r--r--src/libsyntax_pos/symbol.rs2
-rw-r--r--src/test/compile-fail/feature-gate-generators.rs1
-rw-r--r--src/test/compile-fail/generator/borrowing.rs3
-rw-r--r--src/test/compile-fail/generator/no-arguments-on-generators.rs2
-rw-r--r--src/test/compile-fail/generator/not-send-sync.rs2
-rw-r--r--src/test/compile-fail/generator/yield-in-const.rs3
-rw-r--r--src/test/compile-fail/generator/yield-in-function.rs3
-rw-r--r--src/test/compile-fail/generator/yield-in-static.rs3
-rw-r--r--src/test/run-pass/generator/control-flow.rs4
-rw-r--r--src/test/run-pass/generator/drop-env.rs5
-rw-r--r--src/test/run-pass/generator/implicit-argument-dead-when-suspended.rs38
-rw-r--r--src/test/run-pass/generator/iterator-count.rs2
-rw-r--r--src/test/run-pass/generator/panic-drops.rs4
-rw-r--r--src/test/run-pass/generator/panic-safe.rs4
-rw-r--r--src/test/run-pass/generator/resume-after-return.rs4
-rw-r--r--src/test/run-pass/generator/smoke.rs35
68 files changed, 106 insertions, 508 deletions
diff --git a/src/doc/unstable-book/src/language-features/generators.md b/src/doc/unstable-book/src/language-features/generators.md
index 231945db37b..a8d449382ee 100644
--- a/src/doc/unstable-book/src/language-features/generators.md
+++ b/src/doc/unstable-book/src/language-features/generators.md
@@ -36,11 +36,11 @@ fn main() {
         return "foo"
     };
 
-    match generator.resume(()) {
+    match generator.resume() {
         State::Yielded(1) => {}
         _ => panic!("unexpected value from resume"),
     }
-    match generator.resume(()) {
+    match generator.resume() {
         State::Complete("foo") => {}
         _ => panic!("unexpected value from resume"),
     }
@@ -69,9 +69,9 @@ fn main() {
     };
 
     println!("1");
-    generator.resume(());
+    generator.resume();
     println!("3");
-    generator.resume(());
+    generator.resume();
     println!("5");
 }
 ```
@@ -175,8 +175,8 @@ fn main() {
         return ret
     };
 
-    generator.resume(());
-    generator.resume(());
+    generator.resume();
+    generator.resume();
 }
 ```
 
@@ -200,7 +200,7 @@ fn main() {
             type Yield = i32;
             type Return = &'static str;
 
-            fn resume(&mut self, arg: ()) -> State<i32, &'static str> {
+            fn resume(&mut self) -> State<i32, &'static str> {
                 use std::mem;
                 match mem::replace(self, __Generator::Done) {
                     __Generator::Start(s) => {
@@ -223,8 +223,8 @@ fn main() {
         __Generator::Start(ret)
     };
 
-    generator.resume(());
-    generator.resume(());
+    generator.resume();
+    generator.resume();
 }
 ```
 
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index eae8da8dab9..f9eeb74ea00 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -786,12 +786,12 @@ impl<T: ?Sized> AsMut<T> for Box<T> {
 }
 
 #[unstable(feature = "generator_trait", issue = "43122")]
-impl<T, U> Generator<U> for Box<T>
-    where T: Generator<U> + ?Sized
+impl<T> Generator for Box<T>
+    where T: Generator + ?Sized
 {
     type Yield = T::Yield;
     type Return = T::Return;
-    fn resume(&mut self, arg: U) -> State<Self::Yield, Self::Return> {
-        (**self).resume(arg)
+    fn resume(&mut self) -> State<Self::Yield, Self::Return> {
+        (**self).resume()
     }
 }
diff --git a/src/libcore/ops/generator.rs b/src/libcore/ops/generator.rs
index 4d125573afc..44b9835daf5 100644
--- a/src/libcore/ops/generator.rs
+++ b/src/libcore/ops/generator.rs
@@ -56,11 +56,11 @@ pub enum State<Y, R> {
 ///         return "foo"
 ///     };
 ///
-///     match generator.resume(()) {
+///     match generator.resume() {
 ///         State::Yielded(1) => {}
 ///         _ => panic!("unexpected return from resume"),
 ///     }
-///     match generator.resume(()) {
+///     match generator.resume() {
 ///         State::Complete("foo") => {}
 ///         _ => panic!("unexpected return from resume"),
 ///     }
@@ -73,7 +73,7 @@ pub enum State<Y, R> {
 #[cfg_attr(not(stage0), lang = "generator")]
 #[unstable(feature = "generator_trait", issue = "43122")]
 #[fundamental]
-pub trait Generator<Arg = ()> {
+pub trait Generator {
     /// The type of value this generator yields.
     ///
     /// This associated type corresponds to the `yield` expression and the
@@ -116,16 +116,16 @@ pub trait Generator<Arg = ()> {
     /// been returned previously. While generator literals in the language are
     /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
     /// for all implementations of the `Generator` trait.
-    fn resume(&mut self, arg: Arg) -> State<Self::Yield, Self::Return>;
+    fn resume(&mut self) -> State<Self::Yield, Self::Return>;
 }
 
 #[unstable(feature = "generator_trait", issue = "43122")]
-impl<'a, T, U> Generator<U> for &'a mut T
-    where T: Generator<U> + ?Sized
+impl<'a, T> Generator for &'a mut T
+    where T: Generator + ?Sized
 {
     type Yield = T::Yield;
     type Return = T::Return;
-    fn resume(&mut self, arg: U) -> State<Self::Yield, Self::Return> {
-        (**self).resume(arg)
+    fn resume(&mut self) -> State<Self::Yield, Self::Return> {
+        (**self).resume()
     }
 }
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs
index fb205655df2..e7e2c84fc4e 100644
--- a/src/librustc/cfg/construct.rs
+++ b/src/librustc/cfg/construct.rs
@@ -402,7 +402,6 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
 
             hir::ExprClosure(..) |
             hir::ExprLit(..) |
-            hir::ExprImplArg(_) |
             hir::ExprPath(_) => {
                 self.straightline(expr, pred, None::<hir::Expr>.iter())
             }
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 9e411703372..43496540c11 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -399,9 +399,6 @@ pub fn walk_body<'v, V: Visitor<'v>>(visitor: &mut V, body: &'v Body) {
         visitor.visit_id(argument.id);
         visitor.visit_pat(&argument.pat);
     }
-    if let Some(ref impl_arg) = body.impl_arg {
-        visitor.visit_id(impl_arg.id);
-    }
     visitor.visit_expr(&body.value);
 }
 
@@ -1048,9 +1045,6 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
         ExprYield(ref subexpression) => {
             visitor.visit_expr(subexpression);
         }
-        ExprImplArg(id) => {
-            visitor.visit_id(id);
-        },
     }
 }
 
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 3aa7149933c..32fa343e911 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -92,7 +92,7 @@ pub struct LoweringContext<'a> {
     trait_impls: BTreeMap<DefId, Vec<NodeId>>,
     trait_default_impl: BTreeMap<DefId, NodeId>,
 
-    impl_arg: Option<NodeId>,
+    is_generator: hir::IsGenerator,
 
     catch_scopes: Vec<NodeId>,
     loop_scopes: Vec<NodeId>,
@@ -139,7 +139,6 @@ pub fn lower_crate(sess: &Session,
         trait_impls: BTreeMap::new(),
         trait_default_impl: BTreeMap::new(),
         exported_macros: Vec::new(),
-        impl_arg: None,
         catch_scopes: Vec::new(),
         loop_scopes: Vec::new(),
         is_in_loop_condition: false,
@@ -147,6 +146,7 @@ pub fn lower_crate(sess: &Session,
         current_hir_id_owner: vec![(CRATE_DEF_INDEX, 0)],
         item_local_id_counters: NodeMap(),
         node_id_to_hir_id: IndexVec::new(),
+        is_generator: hir::IsGenerator::No,
     }.lower_crate(krate)
 }
 
@@ -365,24 +365,13 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn impl_arg_id(&mut self) -> NodeId {
-        if self.impl_arg.is_none() {
-            self.impl_arg = Some(self.next_id());
-        }
-        self.impl_arg.unwrap()
-    }
-
     fn record_body(&mut self, value: hir::Expr, decl: Option<&FnDecl>)
                    -> hir::BodyId {
-        let span = value.span;
         let body = hir::Body {
             arguments: decl.map_or(hir_vec![], |decl| {
                 decl.inputs.iter().map(|x| self.lower_arg(x)).collect()
             }),
-            impl_arg: self.impl_arg.map(|id| hir::ImplArg {
-                id,
-                span,
-            }),
+            is_generator: self.is_generator == hir::IsGenerator::Yes,
             value,
         };
         let id = body.id();
@@ -443,12 +432,11 @@ impl<'a> LoweringContext<'a> {
     fn lower_body<F>(&mut self, decl: Option<&FnDecl>, f: F) -> hir::BodyId
         where F: FnOnce(&mut LoweringContext) -> hir::Expr
     {
-        let old_impl_arg = self.impl_arg;
-        self.impl_arg = None;
+        let prev = mem::replace(&mut self.is_generator, hir::IsGenerator::No);
         let result = f(self);
         let r = self.record_body(result, decl);
-        self.impl_arg = old_impl_arg;
-        r
+        self.is_generator = prev;
+        return r
     }
 
     fn with_loop_scope<T, F>(&mut self, loop_id: NodeId, f: F) -> T
@@ -1952,13 +1940,13 @@ impl<'a> LoweringContext<'a> {
             ExprKind::Closure(capture_clause, ref decl, ref body, fn_decl_span) => {
                 self.with_new_scopes(|this| {
                     this.with_parent_def(e.id, |this| {
-                        let mut gen = None;
+                        let mut gen = hir::IsGenerator::No;
                         let body_id = this.lower_body(Some(decl), |this| {
                             let e = this.lower_expr(body);
-                            gen = this.impl_arg.map(|_| hir::GeneratorClause::Movable);
+                            gen = this.is_generator;
                             e
                         });
-                        if gen.is_some() && !decl.inputs.is_empty() {
+                        if gen == hir::IsGenerator::Yes && !decl.inputs.is_empty() {
                             this.sess.span_fatal(
                                     fn_decl_span,
                                     &format!("generators cannot have explicit arguments"));
@@ -2104,17 +2092,13 @@ impl<'a> LoweringContext<'a> {
             }
 
             ExprKind::Yield(ref opt_expr) => {
-                self.impl_arg_id();
+                self.is_generator = hir::IsGenerator::Yes;
                 let expr = opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| {
                     self.expr(e.span, hir::ExprTup(hir_vec![]), ThinVec::new())
                 });
                 hir::ExprYield(P(expr))
             }
 
-            ExprKind::ImplArg => {
-                hir::ExprImplArg(self.impl_arg_id())
-            }
-
             // Desugar ExprIfLet
             // From: `if let <pat> = <sub_expr> <body> [<else_opt>]`
             ExprKind::IfLet(ref pat, ref sub_expr, ref body, ref else_opt) => {
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index dfc1c7ad361..d3ae3e0e8e8 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -182,13 +182,6 @@ impl<'hir> Visitor<'hir> for NodeCollector<'hir> {
         });
     }
 
-    fn visit_body(&mut self, b: &'hir Body) {
-        if let Some(ref impl_arg) = b.impl_arg {
-            self.insert(impl_arg.id, NodeImplArg(impl_arg));
-        }
-        intravisit::walk_body(self, b);
-    }
-
     fn visit_fn(&mut self, fk: intravisit::FnKind<'hir>, fd: &'hir FnDecl,
                 b: BodyId, s: Span, id: NodeId) {
         assert_eq!(self.parent_node, id);
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 9a04cef5ee0..6bbff608be4 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -55,7 +55,6 @@ pub enum Node<'hir> {
     NodeTraitRef(&'hir TraitRef),
     NodeLocal(&'hir Pat),
     NodePat(&'hir Pat),
-    NodeImplArg(&'hir ImplArg),
     NodeBlock(&'hir Block),
 
     /// NodeStructCtor represents a tuple struct.
@@ -85,7 +84,6 @@ enum MapEntry<'hir> {
     EntryTy(NodeId, &'hir Ty),
     EntryTraitRef(NodeId, &'hir TraitRef),
     EntryLocal(NodeId, &'hir Pat),
-    EntryImplArg(NodeId, &'hir ImplArg),
     EntryPat(NodeId, &'hir Pat),
     EntryBlock(NodeId, &'hir Block),
     EntryStructCtor(NodeId, &'hir VariantData),
@@ -117,7 +115,6 @@ impl<'hir> MapEntry<'hir> {
             NodeTy(n) => EntryTy(p, n),
             NodeTraitRef(n) => EntryTraitRef(p, n),
             NodeLocal(n) => EntryLocal(p, n),
-            NodeImplArg(n) => EntryImplArg(p, n),
             NodePat(n) => EntryPat(p, n),
             NodeBlock(n) => EntryBlock(p, n),
             NodeStructCtor(n) => EntryStructCtor(p, n),
@@ -139,7 +136,6 @@ impl<'hir> MapEntry<'hir> {
             EntryStmt(id, _) => id,
             EntryTy(id, _) => id,
             EntryTraitRef(id, _) => id,
-            EntryImplArg(id, _) => id,
             EntryLocal(id, _) => id,
             EntryPat(id, _) => id,
             EntryBlock(id, _) => id,
@@ -166,7 +162,6 @@ impl<'hir> MapEntry<'hir> {
             EntryTy(_, n) => NodeTy(n),
             EntryTraitRef(_, n) => NodeTraitRef(n),
             EntryLocal(_, n) => NodeLocal(n),
-            EntryImplArg(_, n) => NodeImplArg(n),
             EntryPat(_, n) => NodePat(n),
             EntryBlock(_, n) => NodeBlock(n),
             EntryStructCtor(_, n) => NodeStructCtor(n),
@@ -327,7 +322,6 @@ impl<'hir> Map<'hir> {
                 EntryTy(p, _) |
                 EntryTraitRef(p, _) |
                 EntryLocal(p, _) |
-                EntryImplArg(p, _) |
                 EntryPat(p, _) |
                 EntryBlock(p, _) |
                 EntryStructCtor(p, _) |
@@ -903,7 +897,6 @@ impl<'hir> Map<'hir> {
             Some(EntryTy(_, ty)) => ty.span,
             Some(EntryTraitRef(_, tr)) => tr.path.span,
             Some(EntryLocal(_, pat)) => pat.span,
-            Some(EntryImplArg(_, impl_arg)) => impl_arg.span,
             Some(EntryPat(_, pat)) => pat.span,
             Some(EntryBlock(_, block)) => block.span,
             Some(EntryStructCtor(_, _)) => self.expect_item(self.get_parent(id)).span,
@@ -1113,7 +1106,6 @@ impl<'a> print::State<'a> {
             }
             NodeLifetime(a)    => self.print_lifetime(&a),
             NodeVisibility(a)  => self.print_visibility(&a),
-            NodeImplArg(_)     => bug!("cannot print ImplArg"),
             NodeTyParam(_)     => bug!("cannot print TyParam"),
             NodeField(_)       => bug!("cannot print StructField"),
             // these cases do not carry enough information in the
@@ -1215,9 +1207,6 @@ fn node_id_to_string(map: &Map, id: NodeId, include_id: bool) -> String {
         Some(NodeLocal(_)) => {
             format!("local {}{}", map.node_to_pretty_string(id), id_str)
         }
-        Some(NodeImplArg(_)) => {
-            format!("impl_arg {}{}", map.node_to_pretty_string(id), id_str)
-        }
         Some(NodePat(_)) => {
             format!("pat {}{}", map.node_to_pretty_string(id), id_str)
         }
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index c90fb056152..8fb7ca643a7 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -925,13 +925,6 @@ pub enum UnsafeSource {
     UserProvided,
 }
 
-/// represents an implicit argument of a generator
-#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub struct ImplArg {
-    pub id: NodeId,
-    pub span: Span,
-}
-
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct BodyId {
     pub node_id: NodeId,
@@ -942,7 +935,7 @@ pub struct BodyId {
 pub struct Body {
     pub arguments: HirVec<Arg>,
     pub value: Expr,
-    pub impl_arg: Option<ImplArg>,
+    pub is_generator: bool,
 }
 
 impl Body {
@@ -951,10 +944,6 @@ impl Body {
             node_id: self.value.id
         }
     }
-
-    pub fn is_generator(&self) -> bool {
-        self.impl_arg.is_some()
-    }
 }
 
 /// An expression
@@ -1025,7 +1014,7 @@ pub enum Expr_ {
     /// The final span is the span of the argument block `|...|`
     ///
     /// This may also be a generator literal, in that case there is an GeneratorClause.
-    ExprClosure(CaptureClause, P<FnDecl>, BodyId, Span, Option<GeneratorClause>),
+    ExprClosure(CaptureClause, P<FnDecl>, BodyId, Span, IsGenerator),
     /// A block (`{ ... }`)
     ExprBlock(P<Block>),
 
@@ -1073,9 +1062,6 @@ pub enum Expr_ {
 
     /// A suspension point for generators. This is `yield <expr>` in Rust.
     ExprYield(P<Expr>),
-
-    /// The argument to a generator
-    ExprImplArg(NodeId),
 }
 
 /// Optionally `Self`-qualified value/type path or associated extension.
@@ -1205,9 +1191,9 @@ pub struct Destination {
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
-pub enum GeneratorClause {
-    Immovable,
-    Movable,
+pub enum IsGenerator {
+    Yes,
+    No,
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, Copy)]
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index f58981f616d..f4d7b101e9c 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1463,12 +1463,8 @@ impl<'a> State<'a> {
             }
             hir::ExprYield(ref expr) => {
                 self.s.word("yield")?;
-                self.s.space()?;
                 self.print_expr(&expr)?;
             }
-            hir::ExprImplArg(_) => {
-                self.s.word("gen arg")?;
-            }
         }
         self.ann.post(self, NodeExpr(expr))?;
         self.end()
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index 39fa0cb44d0..04e8cbeb7ff 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -574,7 +574,6 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::E
                 hir::ExprAgain(..)      |
                 hir::ExprRet(..)        |
                 hir::ExprYield(..)    |
-                hir::ExprImplArg(..)    |
                 hir::ExprInlineAsm(..)  |
                 hir::ExprRepeat(..)     |
                 hir::ExprTup(..)        => {
@@ -654,8 +653,7 @@ impl_stable_hash_for!(enum hir::Expr_ {
     ExprInlineAsm(asm, inputs, outputs),
     ExprStruct(path, fields, base),
     ExprRepeat(val, times),
-    ExprYield(val),
-    ExprImplArg(id)
+    ExprYield(val)
 });
 
 impl_stable_hash_for!(enum hir::LocalSource {
@@ -690,9 +688,9 @@ impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::M
     }
 }
 
-impl_stable_hash_for!(enum hir::GeneratorClause {
-    Immovable,
-    Movable
+impl_stable_hash_for!(enum hir::IsGenerator {
+    Yes,
+    No
 });
 
 impl_stable_hash_for!(enum hir::CaptureClause {
@@ -1031,15 +1029,10 @@ impl_stable_hash_for!(struct hir::Arg {
     id
 });
 
-impl_stable_hash_for!(struct hir::ImplArg {
-    id,
-    span
-});
-
 impl_stable_hash_for!(struct hir::Body {
     arguments,
     value,
-    impl_arg
+    is_generator
 });
 
 impl<'a, 'gcx, 'tcx> HashStable<StableHashingContext<'a, 'gcx, 'tcx>> for hir::BodyId {
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index bbd40c6b168..7042f3993e1 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -143,7 +143,6 @@ for ty::UpvarCapture<'tcx> {
 }
 
 impl_stable_hash_for!(struct ty::GenSig<'tcx> {
-    impl_arg_ty,
     yield_ty,
     return_ty
 });
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 3fa13d7ab9e..a684881c091 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -16,7 +16,6 @@ use ty::{self, Ty, TyInfer, TyVar};
 
 use syntax::ast::NodeId;
 use syntax_pos::Span;
-use syntax_pos::DUMMY_SP;
 
 struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
@@ -24,7 +23,6 @@ struct FindLocalByTypeVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     hir_map: &'a hir::map::Map<'gcx>,
     found_local_pattern: Option<&'gcx Pat>,
     found_arg_pattern: Option<&'gcx Pat>,
-    found_impl_arg: bool,
 }
 
 impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
@@ -70,11 +68,6 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
                 self.found_arg_pattern = Some(&*argument.pat);
             }
         }
-        if let Some(ref impl_arg) = body.impl_arg {
-            if !self.found_impl_arg && self.node_matches_type(impl_arg.id) {
-                self.found_impl_arg = true;
-            }
-        }
         intravisit::walk_body(self, body);
     }
 }
@@ -108,7 +101,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             hir_map: &self.tcx.hir,
             found_local_pattern: None,
             found_arg_pattern: None,
-            found_impl_arg: false,
         };
 
         if let Some(body_id) = body_id {
@@ -145,11 +137,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
         }
 
-        if local_visitor.found_impl_arg {
-            labels.push((DUMMY_SP, format!("consider giving a type to the \
-                                            implicit generator argument")));
-        }
-
         let mut err = struct_span_err!(self.tcx.sess,
                                        err_span,
                                        E0282,
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 59fab366eaf..2d7ce4a82da 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -992,25 +992,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         self.next_region_var(EarlyBoundRegion(span, def.name, def.issue_32330))
     }
 
-    pub fn type_var_for_impl_arg(&self,
-                                span: Span,
-                                def_id: DefId)
-                            -> Ty<'tcx> {
-        let default = Some(type_variable::Default {
-            ty: self.tcx.mk_nil(),
-            origin_span: span,
-            def_id: def_id,
-        });
-
-        let ty_var_id = self.type_variables
-                            .borrow_mut()
-                            .new_var(false,
-                                     TypeVariableOrigin::TypeInference(span),
-                                     default);
-
-        self.tcx.mk_var(ty_var_id)
-    }
-
     /// Create a type inference variable for the given
     /// type parameter definition. The substitutions are
     /// for actual parameters that may be referred to by
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 1154c82cd2e..899068a2b3b 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -528,8 +528,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
             hir::ExprYield(ref value) => {
                 self.consume_expr(&value);
             }
-
-            hir::ExprImplArg(_) => { }
         }
     }
 
diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs
index 98e742c694e..abb75c96c10 100644
--- a/src/librustc/middle/liveness.rs
+++ b/src/librustc/middle/liveness.rs
@@ -249,7 +249,6 @@ struct LocalInfo {
 
 #[derive(Copy, Clone, Debug)]
 enum VarKind {
-    ImplArg(NodeId),
     Arg(NodeId, ast::Name),
     Local(LocalInfo),
     CleanExit
@@ -305,7 +304,7 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
         self.num_vars += 1;
 
         match vk {
-            Local(LocalInfo { id: node_id, .. }) | Arg(node_id, _) | ImplArg(node_id) => {
+            Local(LocalInfo { id: node_id, .. }) | Arg(node_id, _) => {
                 self.variable_map.insert(node_id, v);
             },
             CleanExit => {}
@@ -330,7 +329,6 @@ impl<'a, 'tcx> IrMaps<'a, 'tcx> {
             Local(LocalInfo { name, .. }) | Arg(_, name) => {
                 name.to_string()
             },
-            ImplArg(_) => "<impl-arg>".to_string(),
             CleanExit => "<clean-exit>".to_string()
         }
     }
@@ -367,10 +365,6 @@ fn visit_fn<'a, 'tcx: 'a>(ir: &mut IrMaps<'a, 'tcx>,
         })
     };
 
-    if let Some(ref impl_arg) = body.impl_arg {
-        fn_maps.add_variable(ImplArg(impl_arg.id));
-    }
-
     // gather up the various local variables, significant expressions,
     // and so forth:
     intravisit::walk_fn(&mut fn_maps, fk, decl, body_id, sp, id);
@@ -423,10 +417,6 @@ fn visit_expr<'a, 'tcx>(ir: &mut IrMaps<'a, 'tcx>, expr: &'tcx Expr) {
         }
         intravisit::walk_expr(ir, expr);
       }
-      hir::ExprImplArg(_) => {
-          ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
-          intravisit::walk_expr(ir, expr);
-      }
       hir::ExprClosure(..) => {
         // Interesting control flow (for loops can contain labeled
         // breaks or continues)
@@ -891,10 +881,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
         match expr.node {
           // Interesting cases with control flow or which gen/kill
-          hir::ExprImplArg(arg_id) => {
-              self.access_var(expr.id, arg_id, succ, ACC_READ | ACC_USE, expr.span)
-          }
-
           hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
               self.access_path(expr.id, path, succ, ACC_READ | ACC_USE)
           }
@@ -1226,9 +1212,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
     fn write_lvalue(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
                     -> LiveNode {
         match expr.node {
-          hir::ExprImplArg(arg_id) => {
-              self.access_var(expr.id, arg_id, succ, acc, expr.span)
-          }
           hir::ExprPath(hir::QPath::Resolved(_, ref path)) => {
               self.access_path(expr.id, path, succ, acc)
           }
@@ -1419,7 +1402,7 @@ fn check_expr<'a, 'tcx>(this: &mut Liveness<'a, 'tcx>, expr: &'tcx Expr) {
       hir::ExprCast(..) | hir::ExprUnary(..) | hir::ExprRet(..) |
       hir::ExprBreak(..) | hir::ExprAgain(..) | hir::ExprLit(_) |
       hir::ExprBlock(..) | hir::ExprAddrOf(..) |
-      hir::ExprStruct(..) | hir::ExprRepeat(..) | hir::ExprImplArg(_) |
+      hir::ExprStruct(..) | hir::ExprRepeat(..) |
       hir::ExprClosure(..) | hir::ExprPath(_) | hir::ExprYield(..) |
       hir::ExprBox(..) | hir::ExprType(..) => {
         intravisit::walk_expr(this, expr);
@@ -1442,7 +1425,6 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
                     self.warn_about_dead_assign(expr.span, expr.id, ln, var);
                 }
             }
-            hir::ExprImplArg(_) => bug!(),
             _ => {
                 // For other kinds of lvalues, no checks are required,
                 // and any embedded expressions are actually rvalues
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 92883ca1b11..f06d4a3d9e3 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -602,17 +602,6 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
             self.cat_def(expr.id, expr.span, expr_ty, def)
           }
 
-          hir::ExprImplArg(id) => {
-            Ok(Rc::new(cmt_ {
-                id: expr.id,
-                span: expr.span,
-                cat: Categorization::Local(id),
-                mutbl: MutabilityCategory::McDeclared,
-                ty: expr_ty,
-                note: NoteNone
-            }))
-          },
-
           hir::ExprType(ref e, _) => {
             self.cat_expr(&e)
           }
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index b8b8476d54b..269522e8269 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -1072,9 +1072,6 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionResolutionVisitor<'a, 'tcx> {
         for argument in &body.arguments {
             self.visit_pat(&argument.pat);
         }
-        if let Some(ref impl_arg) = body.impl_arg {
-            record_var_lifetime(self, impl_arg.id, impl_arg.span);
-        }
 
         // The body of the every fn is a root scope.
         self.cx.parent = self.cx.var_parent;
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 2c500aa9c6f..a255221c871 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -181,10 +181,6 @@ impl<'tcx> Mir<'tcx> {
         }
     }
 
-    pub fn impl_arg_lvalue() -> Lvalue<'tcx> {
-        Lvalue::Local(Local::new(1))
-    }
-
     #[inline]
     pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
         &self.basic_blocks
diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs
index f0b812ff968..28abd1577da 100644
--- a/src/librustc/traits/util.rs
+++ b/src/librustc/traits/util.rs
@@ -521,7 +521,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     {
         let trait_ref = ty::TraitRef {
             def_id: fn_trait_def_id,
-            substs: self.mk_substs_trait(self_ty, &[sig.skip_binder().impl_arg_ty]),
+            substs: self.mk_substs_trait(self_ty, &[]),
         };
         ty::Binder((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty))
     }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 648300f9cf4..85218c6baa5 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -1979,7 +1979,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                     },
                 }
             },
-            Some(hir_map::NodeImplArg(_)) => Symbol::intern("impl arg").as_str(),
             r => bug!("Variable id {} maps to {:?}, not local", id, r),
         }
     }
@@ -2000,7 +1999,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             hir::ExprUnary(hir::UnDeref, _) |
             hir::ExprField(..) |
             hir::ExprTupField(..) |
-            hir::ExprImplArg(_) |
             hir::ExprIndex(..) => {
                 true
             }
diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs
index c70831cd551..f93626b7cb1 100644
--- a/src/librustc/ty/structural_impls.rs
+++ b/src/librustc/ty/structural_impls.rs
@@ -304,10 +304,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::adjustment::AutoBorrow<'a> {
 impl<'a, 'tcx> Lift<'tcx> for ty::GenSig<'a> {
     type Lifted = ty::GenSig<'tcx>;
     fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
-        tcx.lift(&(self.impl_arg_ty, self.yield_ty, self.return_ty))
-            .map(|(impl_arg_ty, yield_ty, return_ty)| {
+        tcx.lift(&(self.yield_ty, self.return_ty))
+            .map(|(yield_ty, return_ty)| {
                 ty::GenSig {
-                    impl_arg_ty,
                     yield_ty,
                     return_ty,
                 }
@@ -637,14 +636,12 @@ impl<'tcx> TypeFoldable<'tcx> for ty::TypeAndMut<'tcx> {
 impl<'tcx> TypeFoldable<'tcx> for ty::GenSig<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         ty::GenSig {
-            impl_arg_ty: self.impl_arg_ty.fold_with(folder),
             yield_ty: self.yield_ty.fold_with(folder),
             return_ty: self.return_ty.fold_with(folder),
         }
     }
 
     fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.impl_arg_ty.visit_with(visitor) ||
         self.yield_ty.visit_with(visitor) ||
         self.return_ty.visit_with(visitor)
     }
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 0f0bcdb78b8..9a180b3552d 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -648,7 +648,6 @@ impl<'a, 'tcx> ProjectionTy<'tcx> {
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
 pub struct GenSig<'tcx> {
-    pub impl_arg_ty: Ty<'tcx>,
     pub yield_ty: Ty<'tcx>,
     pub return_ty: Ty<'tcx>,
 }
diff --git a/src/librustc_borrowck/borrowck/gather_loans/mod.rs b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
index 426eef59570..21d6ebe5687 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/mod.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/mod.rs
@@ -133,22 +133,6 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for GatherLoanCtxt<'a, 'tcx> {
                bk={:?}, loan_cause={:?})",
                borrow_id, cmt, loan_region,
                bk, loan_cause);
-
-         let borrows_impl_arg = match cmt.cat {
-             Categorization::Local(id) => match self.bccx.tcx.hir.find(id) {
-                 Some(hir::map::NodeImplArg(..)) => true,
-                 _ => false,
-             },
-             _ => false,
-         };
-
-         if borrows_impl_arg {
-             span_err!(self.bccx.tcx.sess,
-                borrow_span,
-                E0623,
-                "cannot borrow the implicit argument of a generator");
-         }
-
         self.guarantee_valid(borrow_id,
                              borrow_span,
                              cmt,
diff --git a/src/librustc_borrowck/diagnostics.rs b/src/librustc_borrowck/diagnostics.rs
index cc9bdf8c8a5..38dcc731236 100644
--- a/src/librustc_borrowck/diagnostics.rs
+++ b/src/librustc_borrowck/diagnostics.rs
@@ -1191,5 +1191,4 @@ register_diagnostics! {
     E0594, // cannot assign to {}
     E0595, // closure cannot assign to {}
     E0598, // lifetime of {} is too short to guarantee its contents can be...
-    E0623, // borrow of the implicit argument of a generator
 }
diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs
index 659a5e60364..72eeaca8b10 100644
--- a/src/librustc_mir/build/expr/as_lvalue.rs
+++ b/src/librustc_mir/build/expr/as_lvalue.rs
@@ -80,9 +80,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 success.and(slice.index(idx))
             }
             ExprKind::SelfRef => {
-                block.and(Lvalue::Local(Local::new(this.arg_offset + 1)))
-            }
-            ExprKind::ImplArg => {
                 block.and(Lvalue::Local(Local::new(1)))
             }
             ExprKind::VarRef { id } => {
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index 024b1a3483a..c1209f4fbe2 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -241,11 +241,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             }
             ExprKind::Yield { value } => {
                 let value = unpack!(block = this.as_operand(block, scope, value));
-                let impl_arg_ty = this.impl_arg_ty.unwrap();
-                block = unpack!(this.build_drop(block,
-                    expr_span,
-                    Lvalue::Local(Local::new(1)),
-                    impl_arg_ty));
                 let resume = this.cfg.start_new_block();
                 let cleanup = this.generator_drop_cleanup(expr_span);
                 this.cfg.terminate(block, source_info, TerminatorKind::Yield {
@@ -272,7 +267,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             ExprKind::Continue { .. } |
             ExprKind::Return { .. } |
             ExprKind::InlineAsm { .. } |
-            ExprKind::ImplArg |
             ExprKind::StaticRef { .. } => {
                 // these do not have corresponding `Rvalue` variants,
                 // so make an operand and then return that
diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs
index 041e8fe475d..9be306d2848 100644
--- a/src/librustc_mir/build/expr/as_temp.rs
+++ b/src/librustc_mir/build/expr/as_temp.rs
@@ -79,7 +79,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         // anything because no values with a destructor can be created in
         // a constant at this time, even if the type may need dropping.
         if let Some(temp_lifetime) = temp_lifetime {
-            this.schedule_drop(expr_span, temp_lifetime, &temp, expr_ty, false);
+            this.schedule_drop(expr_span, temp_lifetime, &temp, expr_ty);
         }
 
         block.and(temp)
diff --git a/src/librustc_mir/build/expr/category.rs b/src/librustc_mir/build/expr/category.rs
index 7f576666dcd..f05411aacab 100644
--- a/src/librustc_mir/build/expr/category.rs
+++ b/src/librustc_mir/build/expr/category.rs
@@ -50,7 +50,6 @@ impl Category {
             ExprKind::Index { .. } |
             ExprKind::SelfRef |
             ExprKind::VarRef { .. } |
-            ExprKind::ImplArg |
             ExprKind::StaticRef { .. } =>
                 Some(Category::Lvalue),
 
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index ef7533e8d49..e8fb918f76c 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -285,7 +285,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             ExprKind::Deref { .. } |
             ExprKind::Literal { .. } |
             ExprKind::Yield { .. } |
-            ExprKind::ImplArg |
             ExprKind::Field { .. } => {
                 debug_assert!(match Category::of(&expr.kind).unwrap() {
                     Category::Rvalue(RvalueFunc::Into) => false,
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 9e96ae474d0..54f285480ab 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -203,7 +203,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         let local_id = self.var_indices[&var];
         let var_ty = self.local_decls[local_id].ty;
         let extent = self.hir.region_maps.var_scope(var);
-        self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty, false);
+        self.schedule_drop(span, extent, &Lvalue::Local(local_id), var_ty);
     }
 
     pub fn visit_bindings<F>(&mut self, pattern: &Pattern<'tcx>, mut f: &mut F)
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 9a8c43e3286..d8d6c398b51 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -119,14 +119,14 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'t
 
             let arguments = implicit_argument.into_iter().chain(explicit_arguments);
 
-            let (yield_ty, impl_arg_ty, return_ty) = if body.is_generator() {
+            let (yield_ty, return_ty) = if body.is_generator {
                 let gen_sig = cx.tables().generator_sigs[&id].clone().unwrap();
-                (Some(gen_sig.yield_ty), Some(gen_sig.impl_arg_ty), gen_sig.return_ty)
+                (Some(gen_sig.yield_ty), gen_sig.return_ty)
             } else {
-                (None, None, fn_sig.output())
+                (None, fn_sig.output())
             };
 
-            build::construct_fn(cx, id, arguments, abi, return_ty, yield_ty, impl_arg_ty, body)
+            build::construct_fn(cx, id, arguments, abi, return_ty, yield_ty, body)
         } else {
             build::construct_const(cx, body_id)
         };
@@ -244,9 +244,6 @@ struct Builder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
 
     fn_span: Span,
     arg_count: usize,
-    arg_offset: usize,
-
-    impl_arg_ty: Option<Ty<'tcx>>,
 
     /// the current set of scopes, updated as we traverse;
     /// see the `scope` module for more details
@@ -343,7 +340,6 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
                                    abi: Abi,
                                    return_ty: Ty<'gcx>,
                                    yield_ty: Option<Ty<'gcx>>,
-                                   impl_arg_ty: Option<Ty<'gcx>>,
                                    body: &'gcx hir::Body)
                                    -> Mir<'tcx>
     where A: Iterator<Item=(Ty<'gcx>, Option<&'gcx hir::Pat>)>
@@ -352,12 +348,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
 
     let tcx = hir.tcx();
     let span = tcx.hir.span(fn_id);
-    let arg_offset = if impl_arg_ty.is_some() { 1 } else { 0 };
     let mut builder = Builder::new(hir.clone(),
         span,
-        arguments.len() + arg_offset,
-        arg_offset,
-        impl_arg_ty,
+        arguments.len(),
         return_ty);
 
     let call_site_extent = CodeExtent::CallSiteScope(body.id());
@@ -366,7 +359,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
     let source_info = builder.source_info(span);
     unpack!(block = builder.in_scope((call_site_extent, source_info), block, |builder| {
         unpack!(block = builder.in_scope((arg_extent, source_info), block, |builder| {
-            builder.args_and_body(block, &arguments, arg_extent, impl_arg_ty, &body.value)
+            builder.args_and_body(block, &arguments, arg_extent, &body.value)
         }));
         // Attribute epilogue to function's closing brace
         let fn_end = Span { lo: span.hi, ..span };
@@ -424,7 +417,7 @@ fn construct_const<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
     let ty = hir.tables().expr_ty_adjusted(ast_expr);
     let owner_id = tcx.hir.body_owner(body_id);
     let span = tcx.hir.span(owner_id);
-    let mut builder = Builder::new(hir.clone(), span, 0, 0, None, ty);
+    let mut builder = Builder::new(hir.clone(), span, 0, ty);
 
     let mut block = START_BLOCK;
     let expr = builder.hir.mirror(ast_expr);
@@ -444,7 +437,7 @@ fn construct_error<'a, 'gcx, 'tcx>(hir: Cx<'a, 'gcx, 'tcx>,
                                        -> Mir<'tcx> {
     let span = hir.tcx().hir.span(hir.tcx().hir.body_owner(body_id));
     let ty = hir.tcx().types.err;
-    let mut builder = Builder::new(hir, span, 0, 0, None, ty);
+    let mut builder = Builder::new(hir, span, 0, ty);
     let source_info = builder.source_info(span);
     builder.cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
     builder.finish(vec![], ty, None)
@@ -454,8 +447,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     fn new(hir: Cx<'a, 'gcx, 'tcx>,
            span: Span,
            arg_count: usize,
-           arg_offset: usize,
-           impl_arg_ty: Option<Ty<'tcx>>,
            return_ty: Ty<'tcx>)
            -> Builder<'a, 'gcx, 'tcx> {
         let mut builder = Builder {
@@ -463,8 +454,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             cfg: CFG { basic_blocks: IndexVec::new() },
             fn_span: span,
             arg_count: arg_count,
-            arg_offset,
-            impl_arg_ty,
             scopes: vec![],
             visibility_scopes: IndexVec::new(),
             visibility_scope: ARGUMENT_VISIBILITY_SCOPE,
@@ -511,26 +500,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                      mut block: BasicBlock,
                      arguments: &[(Ty<'gcx>, Option<&'gcx hir::Pat>)],
                      argument_extent: CodeExtent,
-                     impl_arg_ty: Option<Ty<'gcx>>,
                      ast_body: &'gcx hir::Expr)
                      -> BlockAnd<()>
     {
-        if let Some(impl_arg_ty) = impl_arg_ty {
-            self.local_decls.push(LocalDecl {
-                mutability: Mutability::Mut,
-                ty: impl_arg_ty,
-                is_user_variable: false,
-                source_info:  SourceInfo {
-                    scope: ARGUMENT_VISIBILITY_SCOPE,
-                    span: self.fn_span,
-                },
-                name: None,
-            });
-            let lvalue = Lvalue::Local(Local::new(1));
-            // Make sure we drop the argument on completion
-            self.schedule_drop(ast_body.span, argument_extent, &lvalue, impl_arg_ty, true);
-        };
-
         // Allocate locals for the function arguments
         for &(ty, pattern) in arguments.iter() {
             // If this is a simple binding pattern, give the local a nice name for debuginfo.
@@ -557,7 +529,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         // Bind the argument patterns
         for (index, &(ty, pattern)) in arguments.iter().enumerate() {
             // Function arguments always get the first Local indices after the return pointer
-            let lvalue = Lvalue::Local(Local::new(self.arg_offset + index + 1));
+            let lvalue = Lvalue::Local(Local::new(index + 1));
 
             if let Some(pattern) = pattern {
                 let pattern = Pattern::from_hir(self.hir.tcx().global_tcx(),
@@ -570,7 +542,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
             // Make sure we drop (parts of) the argument even when not matched on.
             self.schedule_drop(pattern.as_ref().map_or(ast_body.span, |pat| pat.span),
-                               argument_extent, &lvalue, ty, false);
+                               argument_extent, &lvalue, ty);
 
         }
 
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 296d7c19e0e..32b429be4a6 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -124,9 +124,6 @@ pub struct Scope<'tcx> {
     /// end of the vector (top of the stack) first.
     drops: Vec<DropData<'tcx>>,
 
-    /// Is the first drop the drop of the implicit argument?
-    impl_arg_drop: bool,
-
     /// A scope may only have one associated free, because:
     ///
     /// 1. We require a `free` to only be scheduled in the scope of
@@ -254,28 +251,12 @@ impl<'tcx> Scope<'tcx> {
         }
     }
 
-    fn drops(&self, generator_drop: bool) -> &[DropData<'tcx>] {
-        if self.impl_arg_drop && generator_drop {
-            &self.drops[1..]
-        } else {
-            &self.drops[..]
-        }
-    }
-
-    fn drops_mut(&mut self, generator_drop: bool) -> &mut [DropData<'tcx>] {
-        if self.impl_arg_drop && generator_drop {
-            &mut self.drops[1..]
-        } else {
-            &mut self.drops[..]
-        }
-    }
-
     /// Returns the cached entrypoint for diverging exit from this scope.
     ///
     /// Precondition: the caches must be fully filled (i.e. diverge_cleanup is called) in order for
     /// this method to work correctly.
     fn cached_block(&self, generator_drop: bool) -> Option<BasicBlock> {
-        let mut drops = self.drops(generator_drop).iter().rev().filter_map(|data| {
+        let mut drops = self.drops.iter().rev().filter_map(|data| {
             match data.kind {
                 DropKind::Value { cached_block } => {
                     Some(cached_block.get(generator_drop))
@@ -375,7 +356,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             extent: extent,
             needs_cleanup: false,
             drops: vec![],
-            impl_arg_drop: false,
             free: None,
             cached_generator_drop: None,
             cached_exits: FxHashMap()
@@ -617,8 +597,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                          span: Span,
                          extent: CodeExtent,
                          lvalue: &Lvalue<'tcx>,
-                         lvalue_ty: Ty<'tcx>,
-                         impl_arg: bool) {
+                         lvalue_ty: Ty<'tcx>) {
         let needs_drop = self.hir.needs_drop(lvalue_ty);
         let drop_kind = if needs_drop {
             DropKind::Value { cached_block: CachedBlock::default() }
@@ -688,10 +667,6 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 let extent_span = extent.span(&tcx.hir).unwrap();
                 // Attribute scope exit drops to scope's closing brace
                 let scope_end = Span { lo: extent_span.hi, .. extent_span};
-                if impl_arg {
-                    assert!(scope.drops.is_empty());
-                    scope.impl_arg_drop = true;
-                }
                 scope.drops.push(DropData {
                     span: scope_end,
                     location: lvalue.clone(),
@@ -865,7 +840,7 @@ fn build_scope_drops<'tcx>(cfg: &mut CFG<'tcx>,
                            generator_drop: bool)
                            -> BlockAnd<()> {
 
-    let mut iter = scope.drops(generator_drop).iter().rev().peekable();
+    let mut iter = scope.drops.iter().rev().peekable();
     while let Some(drop_data) = iter.next() {
         let source_info = scope.source_info(drop_data.span);
         if let DropKind::Value { .. } = drop_data.kind {
@@ -958,7 +933,7 @@ fn build_diverge_scope<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
     // Next, build up the drops. Here we iterate the vector in
     // *forward* order, so that we generate drops[0] first (right to
     // left in diagram above).
-    for (j, drop_data) in scope.drops_mut(generator_drop).iter_mut().enumerate() {
+    for (j, drop_data) in scope.drops.iter_mut().enumerate() {
         debug!("build_diverge_scope drop_data[{}]: {:?}", j, drop_data);
         // Only full value drops are emitted in the diverging path,
         // not StorageDead.
diff --git a/src/librustc_mir/dataflow/drop_flag_effects.rs b/src/librustc_mir/dataflow/drop_flag_effects.rs
index 0b740e5f028..daafbecc5df 100644
--- a/src/librustc_mir/dataflow/drop_flag_effects.rs
+++ b/src/librustc_mir/dataflow/drop_flag_effects.rs
@@ -299,11 +299,6 @@ pub(crate) fn drop_flag_effects_for_location<'a, 'tcx, F>(
                                           move_data.rev_lookup.find(location),
                                           |moi| callback(moi, DropFlagState::Present))
                 }
-                mir::TerminatorKind::Yield { .. } => {
-                    on_lookup_result_bits(tcx, mir, move_data,
-                                          move_data.rev_lookup.find(&Mir::impl_arg_lvalue()),
-                                          |moi| callback(moi, DropFlagState::Present))
-                }
                 _ => {
                     // other terminators do not contain move-ins
                 }
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index dba396e8139..4d4161d4c80 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -475,7 +475,6 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
             }
 
             TerminatorKind::Yield { ref value,  .. } => {
-                self.create_move_path(&Mir::impl_arg_lvalue());
                 self.gather_operand(loc, value);
             }
 
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 4a223ce61f7..338c46a4c93 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -447,7 +447,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
                 closure_id: def_id,
                 substs: substs,
                 upvars: upvars,
-                generator: gen.is_some(),
+                generator: gen == hir::IsGenerator::Yes,
             }
         }
 
@@ -567,7 +567,6 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
         hir::ExprArray(ref fields) => ExprKind::Array { fields: fields.to_ref() },
         hir::ExprTup(ref fields) => ExprKind::Tuple { fields: fields.to_ref() },
 
-        hir::ExprImplArg(_) => ExprKind::ImplArg,
         hir::ExprYield(ref v) => ExprKind::Yield { value: v.to_ref() },
     };
 
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index a2e9e5c40f9..ff239a2addd 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -249,7 +249,6 @@ pub enum ExprKind<'tcx> {
         outputs: Vec<ExprRef<'tcx>>,
         inputs: Vec<ExprRef<'tcx>>
     },
-    ImplArg,
     Yield {
         value: ExprRef<'tcx>,
     },
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index 472623ec20a..f5a2b1b974c 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -96,11 +96,9 @@ fn find_dead_unwinds<'a, 'tcx>(
                            MaybeInitializedLvals::new(tcx, mir, &env),
                            |bd, p| &bd.move_data().move_paths[p]);
     for (bb, bb_data) in mir.basic_blocks().iter_enumerated() {
-        let impl_arg = Mir::impl_arg_lvalue();
         let location = match bb_data.terminator().kind {
             TerminatorKind::Drop { ref location, unwind: Some(_), .. } |
             TerminatorKind::DropAndReplace { ref location, unwind: Some(_), .. } => location,
-            TerminatorKind::Yield { .. } => &impl_arg,
             _ => continue,
         };
 
@@ -344,11 +342,9 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
     {
         for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
             let terminator = data.terminator();
-            let impl_arg = Mir::impl_arg_lvalue();
             let location = match terminator.kind {
                 TerminatorKind::Drop { ref location, .. } |
                 TerminatorKind::DropAndReplace { ref location, .. } => location,
-                TerminatorKind::Yield { .. } => &impl_arg,
                 _ => continue
             };
 
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index fc5834d6053..603e9d1849f 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -47,35 +47,6 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor {
     }
 }
 
-struct SwapLocalVisitor {
-    a: Local,
-    b: Local,
-}
-
-impl<'tcx> MutVisitor<'tcx> for SwapLocalVisitor {
-    fn visit_local(&mut self,
-                        local: &mut Local) {
-        if *local == self.a {
-            *local = self.b;
-        } else if *local == self.b {
-            *local = self.a;
-        }
-    }
-}
-
-struct InsertLocalVisitor {
-    local: Local,
-}
-
-impl<'tcx> MutVisitor<'tcx> for InsertLocalVisitor {
-    fn visit_local(&mut self,
-                        local: &mut Local) {
-        if local.index() >= self.local.index() {
-            *local = Local::new(local.index() + 1);
-        }
-    }
-}
-
 struct DerefArgVisitor;
 
 impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor {
@@ -251,17 +222,7 @@ fn ensure_generator_state_argument<'a, 'tcx>(
                 def_id: DefId,
                 mir: &mut Mir<'tcx>) -> (Ty<'tcx>, GeneratorInterior<'tcx>) {
     let interior = *tcx.typeck_tables_of(def_id).generator_interiors.get(&node_id).unwrap();
-
-    let gen_ty = mir.local_decls.raw[2].ty;
-
-    // Swap generator and implicit argument
-    SwapLocalVisitor {
-        a: Local::new(1),
-        b: Local::new(2),
-    }.visit_mir(mir);
-
-    mir.local_decls.raw[..].swap(1, 2);
-
+    let gen_ty = mir.local_decls.raw[1].ty;
     (gen_ty, interior)
 }
 
@@ -330,10 +291,6 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
     }
 
-    // The implicit argument is defined after each suspend point so it can never
-    // be live in a suspend point.
-    set.remove(&Local::new(2));
-
     // The generator argument is ignored
     set.remove(&Local::new(1));
 
@@ -513,10 +470,6 @@ fn generate_drop<'a, 'tcx>(
         }
     }
 
-    // Remove the implicit argument
-    mir.arg_count = 1;
-    mir.local_decls.raw.pop();
-
     // Replace the return variable
     let source_info = SourceInfo {
         span: mir.span,
@@ -788,7 +741,7 @@ impl MirPass for StateTransform {
 
         mir.return_ty = ret_ty;
         mir.yield_ty = None;
-        mir.arg_count = 2;
+        mir.arg_count = 1;
         mir.spread_arg = None;
         mir.generator_layout = Some(layout);
 
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index b8521833806..9bc198c59a9 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -437,7 +437,6 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
 
         // Generator expressions
         hir::ExprYield(_) |
-        hir::ExprImplArg(_) |
 
         // Expressions with side-effects.
         hir::ExprAssign(..) |
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index 8cf22e2e4fe..7bbaf50d21b 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -542,7 +542,7 @@ pub fn ty_fn_sig<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                     Kind::from(sig.return_ty)].iter());
                 let ret_ty = tcx.mk_adt(state_adt_ref, state_substs);
 
-                tcx.mk_fn_sig(iter::once(env_ty).chain(iter::once(sig.impl_arg_ty)),
+                tcx.mk_fn_sig(iter::once(env_ty),
                     ret_ty,
                     false,
                     hir::Unsafety::Normal,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 78168f8db71..6125300fd2e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -507,7 +507,6 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     ret_coercion: Option<RefCell<DynamicCoerceMany<'gcx, 'tcx>>>,
 
     yield_ty: Option<Ty<'tcx>>,
-    impl_arg_ty: Option<Ty<'tcx>>,
 
     ps: RefCell<UnsafetyState>,
 
@@ -1012,29 +1011,10 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
         fn_sig.abi
     );
 
-    let def_id = fcx.tcx.hir.local_def_id(fn_id);
     let span = body.value.span;
 
-    if let Some(ref impl_arg) = body.impl_arg {
-        if can_be_generator {
-            let impl_arg_ty = fcx.infcx.type_var_for_impl_arg(span, def_id);
-
-            // Require impl_arg: 'static
-            let cause = traits::ObligationCause::new(span,
-                                                     body.value.id,
-                                                     traits::MiscObligation);
-            fcx.fulfillment_cx.borrow_mut()
-                            .register_region_obligation(impl_arg_ty,
-                                                        fcx.tcx.types.re_static,
-                                                        cause);
-
-            fcx.impl_arg_ty = Some(impl_arg_ty);
-
-            // Write the type to the impl arg id
-            fcx.write_ty(impl_arg.id, impl_arg_ty);
-
-            fcx.yield_ty = Some(fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)));
-        }
+    if body.is_generator && can_be_generator {
+        fcx.yield_ty = Some(fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)));
     }
 
     GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
@@ -1055,9 +1035,8 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
         fcx.write_ty(arg.id, arg_ty);
     }
 
-    let gen_ty = if can_be_generator && body.is_generator() {
+    let gen_ty = if can_be_generator && body.is_generator {
         let gen_sig = ty::GenSig {
-            impl_arg_ty: fcx.impl_arg_ty.unwrap(),
             yield_ty: fcx.yield_ty.unwrap(),
             return_ty: ret_ty,
         };
@@ -1747,7 +1726,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             err_count_on_creation: inh.tcx.sess.err_count(),
             ret_coercion: None,
             yield_ty: None,
-            impl_arg_ty: None,
             ps: RefCell::new(UnsafetyState::function(hir::Unsafety::Normal,
                                                      ast::CRATE_NODE_ID)),
             diverges: Cell::new(Diverges::Maybe),
@@ -2573,7 +2551,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
                 let is_closure = match arg.node {
                     // FIXME: Should this be applied for generators?
-                    hir::ExprClosure(.., None) => true,
+                    hir::ExprClosure(.., hir::IsGenerator::No) => true,
                     _ => false
                 };
 
@@ -3992,25 +3970,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                   }
               }
            }
-          hir::ExprImplArg(_) => {
-            match self.impl_arg_ty {
-                Some(ty) => {
-                    ty
-                }
-                None => {
-                    struct_span_err!(self.tcx.sess, expr.span, E0626,
-                                 "gen arg expression outside of generator literal").emit();
-                    tcx.types.err
-                }
-            }
-          }
           hir::ExprYield(ref value) => {
             match self.yield_ty {
                 Some(ty) => {
                     self.check_expr_coercable_to_type(&value, ty);
                 }
                 None => {
-                    struct_span_err!(self.tcx.sess, expr.span, E0625,
+                    struct_span_err!(self.tcx.sess, expr.span, E0623,
                                  "yield statement outside of generator literal").emit();
                 }
             }
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index bf7bbfa16b2..ffaf6afb6e8 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -78,7 +78,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for InferBorrowKindVisitor<'a, 'gcx, 'tcx> {
             hir::ExprClosure(cc, _, body_id, _, gen) => {
                 let body = self.fcx.tcx.hir.body(body_id);
                 self.visit_body(body);
-                self.fcx.analyze_closure(expr.id, expr.span, body, cc, gen.is_some());
+                self.fcx.analyze_closure(expr.id, expr.span, body, cc,
+                                         gen == hir::IsGenerator::Yes);
             }
 
             _ => { }
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 5c397a98437..2f4a9ce4013 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -36,9 +36,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         for arg in &body.arguments {
             wbcx.visit_node_id(arg.pat.span, arg.id);
         }
-        if let Some(ref impl_arg) = body.impl_arg {
-            wbcx.visit_node_id(impl_arg.span, impl_arg.id);
-        }
         wbcx.visit_body(body);
         wbcx.visit_upvar_borrow_map();
         wbcx.visit_closures();
@@ -328,7 +325,6 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
     fn visit_generator_sigs(&mut self) {
         for (&node_id, gen_sig) in self.fcx.tables.borrow().generator_sigs.iter() {
             let gen_sig = gen_sig.map(|s| ty::GenSig {
-                impl_arg_ty: self.resolve(&s.impl_arg_ty, &node_id),
                 yield_ty: self.resolve(&s.yield_ty, &node_id),
                 return_ty: self.resolve(&s.return_ty, &node_id),
             });
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index fb1c9ea5a92..05f5c4070d3 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1156,7 +1156,7 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         NodeField(field) => icx.to_ty(&field.ty),
 
         NodeExpr(&hir::Expr { node: hir::ExprClosure(.., gen), .. }) => {
-            if gen.is_some() {
+            if gen == hir::IsGenerator::Yes {
                 return tcx.typeck_tables_of(def_id).node_id_to_type(node_id);
             }
 
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 45ae8df387b..b646678d7d2 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -4667,6 +4667,5 @@ register_diagnostics! {
     E0588, // packed struct cannot transitively contain a `[repr(align)]` struct
     E0592, // duplicate definitions with name `{}`
 //  E0613, // Removed (merged with E0609)
-    E0625, // yield statement outside of generator literal
-    E0626, // gen arg expression outside of generator literal
+    E0623, // yield statement outside of generator literal
 }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 1a2299bcf1f..0128bf73a35 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -984,9 +984,6 @@ pub enum ExprKind {
 
     /// A `yield`, with an optional value to be yielded
     Yield(Option<P<Expr>>),
-
-    /// A reference to the implicit argument of a generator
-    ImplArg,
 }
 
 /// The explicit Self type in a "qualified path". The actual
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 0f99761968a..bf19a7e0383 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -1335,11 +1335,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
                                   e.span,
                                   "yield syntax is experimental");
             }
-            ast::ExprKind::ImplArg => {
-                gate_feature_post!(&self, generators,
-                                  e.span,
-                                  "gen arg syntax is experimental");
-            }
             ast::ExprKind::Lit(ref lit) => {
                 if let ast::LitKind::Int(_, ref ty) = lit.node {
                     match *ty {
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 4a86008bb33..580c2aa58a5 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -1304,7 +1304,6 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
                 };
             }
             ExprKind::Yield(ex) => ExprKind::Yield(ex.map(|x| folder.fold_expr(x))),
-            ExprKind::ImplArg => ExprKind::ImplArg,
             ExprKind::Try(ex) => ExprKind::Try(folder.fold_expr(ex)),
             ExprKind::Catch(body) => ExprKind::Catch(folder.fold_block(body)),
         },
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 6b825a9d401..b7ae025db5f 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2146,12 +2146,6 @@ impl<'a> Parser<'a> {
                     assert!(self.eat_keyword(keywords::Catch));
                     return self.parse_catch_expr(lo, attrs);
                 }
-                if self.is_gen_arg() {
-                    assert!(self.eat_keyword(keywords::Gen));
-                    assert!(self.eat_keyword(keywords::Arg));
-                    let hi = self.prev_span;
-                    return Ok(self.mk_expr(lo.to(hi), ExprKind::ImplArg, attrs));
-                }
                 if self.eat_keyword(keywords::Return) {
                     if self.token.can_begin_expr() {
                         let e = self.parse_expr()?;
@@ -3710,11 +3704,6 @@ impl<'a> Parser<'a> {
         self.look_ahead(1, |t| t.is_ident() && !t.is_reserved_ident())
     }
 
-    fn is_gen_arg(&self) -> bool {
-        self.token.is_keyword(keywords::Gen) &&
-        self.look_ahead(1, |t| t.is_keyword(keywords::Arg))
-    }
-
     fn is_defaultness(&self) -> bool {
         // `pub` is included for better error messages
         self.token.is_keyword(keywords::Default) &&
@@ -3818,8 +3807,7 @@ impl<'a> Parser<'a> {
         // Starts like a simple path, but not a union item.
         } else if self.token.is_path_start() &&
                   !self.token.is_qpath_start() &&
-                  !self.is_union_item() &&
-                  !self.is_gen_arg() {
+                  !self.is_union_item() {
             let pth = self.parse_path(PathStyle::Expr)?;
 
             if !self.eat(&token::Not) {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 1412f78b00d..9e36fb83696 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2290,9 +2290,6 @@ impl<'a> State<'a> {
                     _ => ()
                 }
             }
-            ast::ExprKind::ImplArg => {
-                self.s.word("impl arg")?;
-            }
             ast::ExprKind::Try(ref e) => {
                 self.print_expr(e)?;
                 self.s.word("?")?
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index cd8a2f1534b..05077d42a0b 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -787,7 +787,6 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) {
         ExprKind::Yield(ref optional_expression) => {
             walk_list!(visitor, visit_expr, optional_expression);
         }
-        ExprKind::ImplArg => (),
         ExprKind::Try(ref subexpression) => {
             visitor.visit_expr(subexpression)
         }
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index 1123c33c0c2..debac70545a 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -307,8 +307,6 @@ declare_keywords! {
     (56, StaticLifetime, "'static")
     (57, Union,          "union")
     (58, Catch,          "catch")
-    (59, Arg,            "arg")
-    (60, Gen,            "gen")
 }
 
 // If an interner exists in TLS, return it. Otherwise, prepare a fresh one.
diff --git a/src/test/compile-fail/feature-gate-generators.rs b/src/test/compile-fail/feature-gate-generators.rs
index 8371ff4f579..3754f92d8cd 100644
--- a/src/test/compile-fail/feature-gate-generators.rs
+++ b/src/test/compile-fail/feature-gate-generators.rs
@@ -10,5 +10,4 @@
 
 fn main() {
     yield true; //~ ERROR yield syntax is experimental
-    gen arg;  //~ ERROR gen arg syntax is experimental
 }
diff --git a/src/test/compile-fail/generator/borrowing.rs b/src/test/compile-fail/generator/borrowing.rs
index ea2189d9f81..0bbb212b09b 100644
--- a/src/test/compile-fail/generator/borrowing.rs
+++ b/src/test/compile-fail/generator/borrowing.rs
@@ -16,14 +16,13 @@ use std::cell::Cell;
 fn main() {
     let _b = {
         let a = 3;
-        (|| yield &a).resume(())
+        (|| yield &a).resume()
         //~^ ERROR: `a` does not live long enough
     };
 
     let _b = {
         let a = 3;
         || {
-            let _: () = gen arg; // FIXME: shouldn't be needed for inference
             yield &a
             //~^ ERROR: `a` does not live long enough
         }
diff --git a/src/test/compile-fail/generator/no-arguments-on-generators.rs b/src/test/compile-fail/generator/no-arguments-on-generators.rs
index 0f8d29e5cab..a7e98fe4509 100644
--- a/src/test/compile-fail/generator/no-arguments-on-generators.rs
+++ b/src/test/compile-fail/generator/no-arguments-on-generators.rs
@@ -14,4 +14,4 @@ fn main() {
     let gen = |start| { //~ ERROR generators cannot have explicit arguments
         yield;
     };
-}
\ No newline at end of file
+}
diff --git a/src/test/compile-fail/generator/not-send-sync.rs b/src/test/compile-fail/generator/not-send-sync.rs
index 6cfc8dd333e..31f80029b06 100644
--- a/src/test/compile-fail/generator/not-send-sync.rs
+++ b/src/test/compile-fail/generator/not-send-sync.rs
@@ -21,7 +21,6 @@ fn main() {
         //~^ ERROR: Sync` is not satisfied
         let a = Cell::new(2);
         yield;
-        let _: () = gen arg;
     });
 
     let a = Cell::new(2);
@@ -29,6 +28,5 @@ fn main() {
         //~^ ERROR: Sync` is not satisfied
         drop(&a);
         yield;
-        let _: () = gen arg;
     });
 }
diff --git a/src/test/compile-fail/generator/yield-in-const.rs b/src/test/compile-fail/generator/yield-in-const.rs
index 5176f3c5f56..e166d265159 100644
--- a/src/test/compile-fail/generator/yield-in-const.rs
+++ b/src/test/compile-fail/generator/yield-in-const.rs
@@ -10,6 +10,5 @@
 
 #![feature(generators)]
 
-const A: u8 = { yield 3u8; gen arg; 3u8};
+const A: u8 = { yield 3u8; 3u8};
 //~^ ERROR yield statement outside
-//~| ERROR gen arg expression outside
diff --git a/src/test/compile-fail/generator/yield-in-function.rs b/src/test/compile-fail/generator/yield-in-function.rs
index 95ec1224421..2f6c5a9ef75 100644
--- a/src/test/compile-fail/generator/yield-in-function.rs
+++ b/src/test/compile-fail/generator/yield-in-function.rs
@@ -10,6 +10,5 @@
 
 #![feature(generators)]
 
-fn main() { yield; gen arg; }
+fn main() { yield; }
 //~^ ERROR yield statement outside
-//~| ERROR gen arg expression outside
diff --git a/src/test/compile-fail/generator/yield-in-static.rs b/src/test/compile-fail/generator/yield-in-static.rs
index f4cad13ce8e..823a2aa425e 100644
--- a/src/test/compile-fail/generator/yield-in-static.rs
+++ b/src/test/compile-fail/generator/yield-in-static.rs
@@ -10,6 +10,5 @@
 
 #![feature(generators)]
 
-static B: u8 = { yield 3u8; gen arg; 3u8};
+static B: u8 = { yield 3u8; 3u8};
 //~^ ERROR yield statement outside
-//~| ERROR gen arg expression outside
diff --git a/src/test/run-pass/generator/control-flow.rs b/src/test/run-pass/generator/control-flow.rs
index 911bb96b582..d627e835c63 100644
--- a/src/test/run-pass/generator/control-flow.rs
+++ b/src/test/run-pass/generator/control-flow.rs
@@ -13,10 +13,10 @@
 use std::ops::{State, Generator};
 
 fn finish<T>(mut amt: usize, mut t: T) -> T::Return
-    where T: Generator<(), Yield = ()>
+    where T: Generator<Yield = ()>
 {
     loop {
-        match t.resume(()) {
+        match t.resume() {
             State::Yielded(()) => amt = amt.checked_sub(1).unwrap(),
             State::Complete(ret) => {
                 assert_eq!(amt, 0);
diff --git a/src/test/run-pass/generator/drop-env.rs b/src/test/run-pass/generator/drop-env.rs
index be4e48f1f4c..ac42a25899d 100644
--- a/src/test/run-pass/generator/drop-env.rs
+++ b/src/test/run-pass/generator/drop-env.rs
@@ -37,7 +37,7 @@ fn t1() {
     };
 
     let n = A.load(Ordering::SeqCst);
-    drop(foo.resume(()));
+    drop(foo.resume());
     assert_eq!(A.load(Ordering::SeqCst), n);
     drop(foo);
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
@@ -50,7 +50,7 @@ fn t2() {
     };
 
     let n = A.load(Ordering::SeqCst);
-    drop(foo.resume(()));
+    drop(foo.resume());
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
     drop(foo);
     assert_eq!(A.load(Ordering::SeqCst), n + 1);
@@ -59,7 +59,6 @@ fn t2() {
 fn t3() {
     let b = B;
     let foo = || {
-        let _: () = gen arg; // FIXME: this line should not be necessary
         yield;
         drop(b);
     };
diff --git a/src/test/run-pass/generator/implicit-argument-dead-when-suspended.rs b/src/test/run-pass/generator/implicit-argument-dead-when-suspended.rs
deleted file mode 100644
index 635d8fb3cdc..00000000000
--- a/src/test/run-pass/generator/implicit-argument-dead-when-suspended.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(generators, generator_trait)]
-
-use std::ops::Generator;
-use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
-
-static A: AtomicUsize = ATOMIC_USIZE_INIT;
-
-struct B;
-
-impl Drop for B {
-    fn drop(&mut self) {
-        A.fetch_add(1, Ordering::SeqCst);
-    }
-}
-
-fn main() {
-    let b = B;
-
-    let mut gen = || {
-        yield;
-    };
-
-    assert_eq!(A.load(Ordering::SeqCst), 0);
-    gen.resume(b);
-    assert_eq!(A.load(Ordering::SeqCst), 1);
-    drop(gen);
-    assert_eq!(A.load(Ordering::SeqCst), 1);
-}
diff --git a/src/test/run-pass/generator/iterator-count.rs b/src/test/run-pass/generator/iterator-count.rs
index 45ba663873b..8de0e71b857 100644
--- a/src/test/run-pass/generator/iterator-count.rs
+++ b/src/test/run-pass/generator/iterator-count.rs
@@ -18,7 +18,7 @@ impl<T: Generator<Return = ()>> Iterator for W<T> {
     type Item = T::Yield;
 
     fn next(&mut self) -> Option<Self::Item> {
-        match self.0.resume(()) {
+        match self.0.resume() {
             State::Complete(..) => None,
             State::Yielded(v) => Some(v),
         }
diff --git a/src/test/run-pass/generator/panic-drops.rs b/src/test/run-pass/generator/panic-drops.rs
index 6b9d7da197f..4837f68be5e 100644
--- a/src/test/run-pass/generator/panic-drops.rs
+++ b/src/test/run-pass/generator/panic-drops.rs
@@ -36,7 +36,7 @@ fn main() {
 
     assert_eq!(A.load(Ordering::SeqCst), 0);
     let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        foo.resume(())
+        foo.resume()
     }));
     assert!(res.is_err());
     assert_eq!(A.load(Ordering::SeqCst), 1);
@@ -51,7 +51,7 @@ fn main() {
 
     assert_eq!(A.load(Ordering::SeqCst), 1);
     let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        foo.resume(())
+        foo.resume()
     }));
     assert!(res.is_err());
     assert_eq!(A.load(Ordering::SeqCst), 1);
diff --git a/src/test/run-pass/generator/panic-safe.rs b/src/test/run-pass/generator/panic-safe.rs
index 7d86d7b6d94..a583f42b93d 100644
--- a/src/test/run-pass/generator/panic-safe.rs
+++ b/src/test/run-pass/generator/panic-safe.rs
@@ -22,13 +22,13 @@ fn main() {
     };
 
     let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-        foo.resume(())
+        foo.resume()
     }));
     assert!(res.is_err());
 
     for _ in 0..10 {
         let res = panic::catch_unwind(panic::AssertUnwindSafe(|| {
-            foo.resume(())
+            foo.resume()
         }));
         assert!(res.is_err());
     }
diff --git a/src/test/run-pass/generator/resume-after-return.rs b/src/test/run-pass/generator/resume-after-return.rs
index ca85d2545c8..d5f81d5eecd 100644
--- a/src/test/run-pass/generator/resume-after-return.rs
+++ b/src/test/run-pass/generator/resume-after-return.rs
@@ -21,12 +21,12 @@ fn main() {
         yield;
     };
 
-    match foo.resume(()) {
+    match foo.resume() {
         State::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
 
-    match panic::catch_unwind(move || foo.resume(())) {
+    match panic::catch_unwind(move || foo.resume()) {
         Ok(_) => panic!("generator successfully resumed"),
         Err(_) => {}
     }
diff --git a/src/test/run-pass/generator/smoke.rs b/src/test/run-pass/generator/smoke.rs
index daa32aa3213..21c7b434d2a 100644
--- a/src/test/run-pass/generator/smoke.rs
+++ b/src/test/run-pass/generator/smoke.rs
@@ -23,7 +23,7 @@ fn simple() {
         }
     };
 
-    match foo.resume(()) {
+    match foo.resume() {
         State::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -39,7 +39,7 @@ fn return_capture() {
         a
     };
 
-    match foo.resume(()) {
+    match foo.resume() {
         State::Complete(ref s) if *s == "foo" => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -51,11 +51,11 @@ fn simple_yield() {
         yield;
     };
 
-    match foo.resume(()) {
+    match foo.resume() {
         State::Yielded(()) => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume(()) {
+    match foo.resume() {
         State::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -68,11 +68,11 @@ fn yield_capture() {
         yield b;
     };
 
-    match foo.resume(()) {
+    match foo.resume() {
         State::Yielded(ref s) if *s == "foo" => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume(()) {
+    match foo.resume() {
         State::Complete(()) => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -85,11 +85,11 @@ fn simple_yield_value() {
         return String::from("foo")
     };
 
-    match foo.resume(()) {
+    match foo.resume() {
         State::Yielded(ref s) if *s == "bar" => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume(()) {
+    match foo.resume() {
         State::Complete(ref s) if *s == "foo" => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -103,11 +103,11 @@ fn return_after_yield() {
         return a
     };
 
-    match foo.resume(()) {
+    match foo.resume() {
         State::Yielded(()) => {}
         s => panic!("bad state: {:?}", s),
     }
-    match foo.resume(()) {
+    match foo.resume() {
         State::Complete(ref s) if *s == "foo" => {}
         s => panic!("bad state: {:?}", s),
     }
@@ -116,40 +116,33 @@ fn return_after_yield() {
 #[test]
 fn send_and_sync() {
     assert_send_sync(|| {
-        let _: () = gen arg;
         yield
     });
     assert_send_sync(|| {
-        let _: () = gen arg;
         yield String::from("foo");
     });
     assert_send_sync(|| {
-        let _: () = gen arg;
         yield;
         return String::from("foo");
     });
     let a = 3;
     assert_send_sync(|| {
-        let _: () = gen arg;
         yield a;
         return
     });
     let a = 3;
     assert_send_sync(move || {
-        let _: () = gen arg;
         yield a;
         return
     });
     let a = String::from("a");
     assert_send_sync(|| {
-        let _: () = gen arg;
         yield ;
         drop(a);
         return
     });
     let a = String::from("a");
     assert_send_sync(move || {
-        let _: () = gen arg;
         yield ;
         drop(a);
         return
@@ -162,11 +155,11 @@ fn send_and_sync() {
 fn send_over_threads() {
     let mut foo = || { yield };
     thread::spawn(move || {
-        match foo.resume(()) {
+        match foo.resume() {
             State::Yielded(()) => {}
             s => panic!("bad state: {:?}", s),
         }
-        match foo.resume(()) {
+        match foo.resume() {
             State::Complete(()) => {}
             s => panic!("bad state: {:?}", s),
         }
@@ -175,11 +168,11 @@ fn send_over_threads() {
     let a = String::from("a");
     let mut foo = || { yield a };
     thread::spawn(move || {
-        match foo.resume(()) {
+        match foo.resume() {
             State::Yielded(ref s) if *s == "a" => {}
             s => panic!("bad state: {:?}", s),
         }
-        match foo.resume(()) {
+        match foo.resume() {
             State::Complete(()) => {}
             s => panic!("bad state: {:?}", s),
         }