Make yield and gen arg outside generator literals an error and update tests
This commit is contained in:
parent
5efb0cbe04
commit
bc9b4deeb5
@ -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 {
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
|
15
src/test/compile-fail/generator/yield-in-const.rs
Normal file
15
src/test/compile-fail/generator/yield-in-const.rs
Normal file
@ -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
|
15
src/test/compile-fail/generator/yield-in-function.rs
Normal file
15
src/test/compile-fail/generator/yield-in-function.rs
Normal file
@ -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
|
@ -10,14 +10,6 @@
|
||||
|
||||
#![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
|
@ -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));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user