mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 18:53:39 +00:00
Remove support for gen arg
This commit is contained in:
parent
93172045c8
commit
09a5d319ab
@ -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();
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)]
|
||||
|
@ -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()
|
||||
|
@ -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 {
|
||||
|
@ -143,7 +143,6 @@ for ty::UpvarCapture<'tcx> {
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct ty::GenSig<'tcx> {
|
||||
impl_arg_ty,
|
||||
yield_ty,
|
||||
return_ty
|
||||
});
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -528,8 +528,6 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
|
||||
hir::ExprYield(ref value) => {
|
||||
self.consume_expr(&value);
|
||||
}
|
||||
|
||||
hir::ExprImplArg(_) => { }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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>,
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 } => {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -50,7 +50,6 @@ impl Category {
|
||||
ExprKind::Index { .. } |
|
||||
ExprKind::SelfRef |
|
||||
ExprKind::VarRef { .. } |
|
||||
ExprKind::ImplArg |
|
||||
ExprKind::StaticRef { .. } =>
|
||||
Some(Category::Lvalue),
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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() },
|
||||
};
|
||||
|
||||
|
@ -249,7 +249,6 @@ pub enum ExprKind<'tcx> {
|
||||
outputs: Vec<ExprRef<'tcx>>,
|
||||
inputs: Vec<ExprRef<'tcx>>
|
||||
},
|
||||
ImplArg,
|
||||
Yield {
|
||||
value: ExprRef<'tcx>,
|
||||
},
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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(..) |
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
_ => { }
|
||||
|
@ -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),
|
||||
});
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)),
|
||||
},
|
||||
|
@ -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) {
|
||||
|
@ -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("?")?
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -10,5 +10,4 @@
|
||||
|
||||
fn main() {
|
||||
yield true; //~ ERROR yield syntax is experimental
|
||||
gen arg; //~ ERROR gen arg syntax is experimental
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -14,4 +14,4 @@ fn main() {
|
||||
let gen = |start| { //~ ERROR generators cannot have explicit arguments
|
||||
yield;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -10,6 +10,5 @@
|
||||
|
||||
#![feature(generators)]
|
||||
|
||||
fn main() { yield; gen arg; }
|
||||
fn main() { yield; }
|
||||
//~^ ERROR yield statement outside
|
||||
//~| ERROR gen arg expression outside
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
@ -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),
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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(_) => {}
|
||||
}
|
||||
|
@ -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),
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user