]> git.lizzy.rs Git - rust.git/commitdiff
Make yield and gen arg outside generator literals an error and update tests
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Sat, 8 Jul 2017 17:30:14 +0000 (19:30 +0200)
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Fri, 28 Jul 2017 13:46:23 +0000 (15:46 +0200)
src/librustc_typeck/check/closure.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/diagnostics.rs
src/test/compile-fail/generator/invalid-positions.rs [deleted file]
src/test/compile-fail/generator/yield-in-const.rs [new file with mode: 0644]
src/test/compile-fail/generator/yield-in-function.rs [new file with mode: 0644]
src/test/compile-fail/generator/yield-in-static.rs [new file with mode: 0644]
src/test/run-pass/generator/iterator-count.rs

index ae64db88d8c5fa1bfec98442fa5f1b92cd153f3f..0f68b15977848d7ace2f1ce14b9925abc2598e9e 100644 (file)
@@ -82,7 +82,7 @@ fn check_closure(&self,
                                                             self.param_env,
                                                             &fn_sig);
 
-        let interior = check_fn(self, self.param_env, fn_sig, decl, expr.id, body).1;
+        let interior = check_fn(self, self.param_env, fn_sig, decl, expr.id, body, true).1;
 
         if let Some(interior) = interior {
             let closure_substs = ty::ClosureSubsts {
index cf8b1d9c8f268c94bb578313ec2770edd1934d3d..1d1631c4fa7e7a8c005257344e3bfc01fca35670 100644 (file)
@@ -871,7 +871,7 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                   param_env,
                                                   &fn_sig);
 
-            check_fn(&inh, param_env, fn_sig, decl, id, body).0
+            check_fn(&inh, param_env, fn_sig, decl, id, body, false).0
         } else {
             let fcx = FnCtxt::new(&inh, param_env, body.value.id);
             let expected_type = tcx.type_of(def_id);
@@ -987,7 +987,8 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
                             fn_sig: ty::FnSig<'tcx>,
                             decl: &'gcx hir::FnDecl,
                             fn_id: ast::NodeId,
-                            body: &'gcx hir::Body)
+                            body: &'gcx hir::Body,
+                            can_be_generator: bool)
                             -> (FnCtxt<'a, 'gcx, 'tcx>, Option<ty::GeneratorInterior<'tcx>>)
 {
     let mut fn_sig = fn_sig.clone();
@@ -1014,22 +1015,30 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     let def_id = fcx.tcx.hir.local_def_id(fn_id);
     let span = body.value.span;
 
+    if fcx.tcx.sess.verbose() {
+        println!("checking body {} {}", fn_id, can_be_generator);
+    }
+
     if let Some(ref impl_arg) = body.impl_arg {
-        let impl_arg_ty = fcx.infcx.type_var_for_impl_arg(span, def_id);
+        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);
+            // 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);
+            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);
+            // Write the type to the impl arg id
+            fcx.write_ty(impl_arg.id, impl_arg_ty);
 
-        fcx.suspend_ty = Some(fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)));
+            fcx.suspend_ty = Some(fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)));
+        }
     }
 
     GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
@@ -1050,7 +1059,7 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
         fcx.write_ty(arg.id, arg_ty);
     }
 
-    let gen_ty = if 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(),
             suspend_ty: fcx.suspend_ty.unwrap(),
@@ -3994,7 +4003,7 @@ fn check_expr_kind(&self,
                 }
                 None => {
                     struct_span_err!(self.tcx.sess, expr.span, E0803,
-                                 "impl arg expression outside of function body").emit();
+                                 "gen arg expression outside of generator literal").emit();
                     tcx.types.err
                 }
             }
@@ -4006,7 +4015,7 @@ fn check_expr_kind(&self,
                 }
                 None => {
                     struct_span_err!(self.tcx.sess, expr.span, E0802,
-                                 "yield statement outside of function body").emit();
+                                 "yield statement outside of generator literal").emit();
                 }
             }
             tcx.mk_nil()
index 4313aa59202f9c5996461a771d9e4612ca35821a..0463f82ccce25ab30d652ecf6260b2630f918612 100644 (file)
@@ -4668,7 +4668,7 @@ fn i_am_a_function() {}
     E0592, // duplicate definitions with name `{}`
 //  E0613, // Removed (merged with E0609)
     E0801, // unexpected generator return
-    E0802, // yield statement outside of function body
-    E0803, // impl arg expression outside of function body
+    E0802, // yield statement outside of generator literal
+    E0803, // gen arg expression outside of generator literal
     E0804, // cannot determine the type for the implicit argument of this generator
 }
diff --git a/src/test/compile-fail/generator/invalid-positions.rs b/src/test/compile-fail/generator/invalid-positions.rs
deleted file mode 100644 (file)
index c2f5b20..0000000
+++ /dev/null
@@ -1,23 +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)]
-
-const A: u8 = { yield 3u8; gen arg; 3u8};
-//~^ ERROR yield statement outside
-//~| ERROR gen arg expression outside
-
-static B: u8 = { yield 3u8; gen arg; 3u8};
-//~^ ERROR yield statement outside
-//~| ERROR gen arg expression outside
-
-fn main() { yield; gen arg; }
-//~^ ERROR yield statement outside
-//~| ERROR gen arg expression outside
diff --git a/src/test/compile-fail/generator/yield-in-const.rs b/src/test/compile-fail/generator/yield-in-const.rs
new file mode 100644 (file)
index 0000000..5176f3c
--- /dev/null
@@ -0,0 +1,15 @@
+// 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)]
+
+const A: u8 = { yield 3u8; gen arg; 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
new file mode 100644 (file)
index 0000000..95ec122
--- /dev/null
@@ -0,0 +1,15 @@
+// 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)]
+
+fn main() { yield; gen arg; }
+//~^ 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
new file mode 100644 (file)
index 0000000..f4cad13
--- /dev/null
@@ -0,0 +1,15 @@
+// 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)]
+
+static B: u8 = { yield 3u8; gen arg; 3u8};
+//~^ ERROR yield statement outside
+//~| ERROR gen arg expression outside
index c415ef2beb30438eff7f3b7260c0f07968abd6e8..e44aa0592357104f4dccdaacb8f6e0ff346dc987 100644 (file)
@@ -34,14 +34,15 @@ fn test() -> impl Generator<Return=(), Yield=u8> {
 }
 
 fn main() {
-    let start = 6;
     let end = 11;
 
-    let closure_test = || {
-        for i in start..end {
-            yield i
+    let closure_test = |start| {
+        || {
+            for i in start..end {
+                yield i
+            }
         }
     };
 
-    assert!(W(test()).chain(W(closure_test)).eq(1..11));
+    assert!(W(test()).chain(W(closure_test(6))).eq(1..11));
 }