Remove support for gen arg

This commit is contained in:
Alex Crichton 2017-07-11 12:57:05 -07:00 committed by John Kåre Alsaker
parent 93172045c8
commit 09a5d319ab
68 changed files with 106 additions and 508 deletions

View File

@ -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();
}
```

View File

@ -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()
}
}

View File

@ -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()
}
}

View File

@ -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())
}

View File

@ -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);
},
}
}

View File

@ -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) => {

View File

@ -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);

View File

@ -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)
}

View File

@ -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)]

View File

@ -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()

View File

@ -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 {

View File

@ -143,7 +143,6 @@ for ty::UpvarCapture<'tcx> {
}
impl_stable_hash_for!(struct ty::GenSig<'tcx> {
impl_arg_ty,
yield_ty,
return_ty
});

View File

@ -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,

View File

@ -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

View File

@ -528,8 +528,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
hir::ExprYield(ref value) => {
self.consume_expr(&value);
}
hir::ExprImplArg(_) => { }
}
}

View File

@ -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

View File

@ -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)
}

View File

@ -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;

View File

@ -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

View File

@ -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))
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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>,
}

View File

@ -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,

View File

@ -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
}

View File

@ -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 } => {

View File

@ -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

View File

@ -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)

View File

@ -50,7 +50,6 @@ impl Category {
ExprKind::Index { .. } |
ExprKind::SelfRef |
ExprKind::VarRef { .. } |
ExprKind::ImplArg |
ExprKind::StaticRef { .. } =>
Some(Category::Lvalue),

View File

@ -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,

View File

@ -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)

View File

@ -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);
}

View File

@ -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.

View File

@ -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
}

View File

@ -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);
}

View File

@ -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() },
};

View File

@ -249,7 +249,6 @@ pub enum ExprKind<'tcx> {
outputs: Vec<ExprRef<'tcx>>,
inputs: Vec<ExprRef<'tcx>>
},
ImplArg,
Yield {
value: ExprRef<'tcx>,
},

View File

@ -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
};

View File

@ -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);

View File

@ -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(..) |

View File

@ -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,

View File

@ -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();
}
}

View File

@ -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);
}
_ => { }

View File

@ -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),
});

View File

@ -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);
}

View File

@ -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
}

View File

@ -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

View File

@ -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 {

View File

@ -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)),
},

View File

@ -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) {

View File

@ -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("?")?

View File

@ -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)
}

View File

@ -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.

View File

@ -10,5 +10,4 @@
fn main() {
yield true; //~ ERROR yield syntax is experimental
gen arg; //~ ERROR gen arg syntax is experimental
}

View File

@ -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
}

View File

@ -14,4 +14,4 @@ fn main() {
let gen = |start| { //~ ERROR generators cannot have explicit arguments
yield;
};
}
}

View File

@ -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;
});
}

View File

@ -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

View File

@ -10,6 +10,5 @@
#![feature(generators)]
fn main() { yield; gen arg; }
fn main() { yield; }
//~^ ERROR yield statement outside
//~| ERROR gen arg expression outside

View File

@ -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

View File

@ -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);

View File

@ -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);
};

View File

@ -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);
}

View File

@ -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),
}

View File

@ -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);

View File

@ -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());
}

View File

@ -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(_) => {}
}

View File

@ -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),
}