Skip to content

Commit

Permalink
Rollup merge of rust-lang#63545 - Centril:gate-yield-preexp, r=oli-obk
Browse files Browse the repository at this point in the history
Feature gate 'yield $expr?' pre-expansion

Also improve the overall ergonomics of pre-expansion gating in general.

r? @Zoxc
  • Loading branch information
Centril authored Aug 16, 2019
2 parents 85ba0ff + 20661f1 commit 1ac66dd
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 31 deletions.
40 changes: 10 additions & 30 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ use crate::tokenstream::TokenTree;

use errors::{Applicability, DiagnosticBuilder, Handler};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lock;
use rustc_target::spec::abi::Abi;
use syntax_pos::{Span, DUMMY_SP, MultiSpan};
use log::debug;
Expand Down Expand Up @@ -2088,11 +2087,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
"type ascription is experimental");
}
}
ast::ExprKind::Yield(..) => {
gate_feature_post!(&self, generators,
e.span,
"yield syntax is experimental");
}
ast::ExprKind::TryBlock(_) => {
gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
}
Expand Down Expand Up @@ -2427,10 +2421,6 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute],
features
}

fn for_each_in_lock<T>(vec: &Lock<Vec<T>>, f: impl Fn(&T)) {
vec.borrow().iter().for_each(f);
}

pub fn check_crate(krate: &ast::Crate,
sess: &ParseSess,
features: &Features,
Expand All @@ -2443,26 +2433,16 @@ pub fn check_crate(krate: &ast::Crate,
plugin_attributes,
};

for_each_in_lock(&sess.param_attr_spans, |span| gate_feature!(
&ctx,
param_attrs,
*span,
"attributes on function parameters are unstable"
));

for_each_in_lock(&sess.let_chains_spans, |span| gate_feature!(
&ctx,
let_chains,
*span,
"`let` expressions in this position are experimental"
));

for_each_in_lock(&sess.async_closure_spans, |span| gate_feature!(
&ctx,
async_closure,
*span,
"async closures are unstable"
));
macro_rules! gate_all {
($spans:ident, $gate:ident, $msg:literal) => {
for span in &*sess.$spans.borrow() { gate_feature!(&ctx, $gate, *span, $msg); }
}
}

gate_all!(param_attr_spans, param_attrs, "attributes on function parameters are unstable");
gate_all!(let_chains_spans, let_chains, "`let` expressions in this position are experimental");
gate_all!(async_closure_spans, async_closure, "async closures are unstable");
gate_all!(yield_spans, generators, "yield syntax is experimental");

let visitor = &mut PostExpansionVisitor {
context: &ctx,
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/parse/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ pub struct ParseSess {
pub let_chains_spans: Lock<Vec<Span>>,
// Places where `async || ..` exprs were used and should be feature gated.
pub async_closure_spans: Lock<Vec<Span>>,
// Places where `yield e?` exprs were used and should be feature gated.
pub yield_spans: Lock<Vec<Span>>,
pub injected_crate_name: Once<Symbol>,
}

Expand Down Expand Up @@ -92,6 +94,7 @@ impl ParseSess {
param_attr_spans: Lock::new(Vec::new()),
let_chains_spans: Lock::new(Vec::new()),
async_closure_spans: Lock::new(Vec::new()),
yield_spans: Lock::new(Vec::new()),
injected_crate_name: Once::new(),
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/libsyntax/parse/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,9 @@ impl<'a> Parser<'a> {
} else {
ex = ExprKind::Yield(None);
}

let span = lo.to(hi);
self.sess.yield_spans.borrow_mut().push(span);
} else if self.eat_keyword(kw::Let) {
return self.parse_let_expr(attrs);
} else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/feature-gates/feature-gate-generators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@ fn main() {
yield true; //~ ERROR yield syntax is experimental
//~^ ERROR yield statement outside of generator literal
}

#[cfg(FALSE)]
fn foo() {
yield; //~ ERROR yield syntax is experimental
yield 0; //~ ERROR yield syntax is experimental
}
20 changes: 19 additions & 1 deletion src/test/ui/feature-gates/feature-gate-generators.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,30 @@ LL | yield true;
= note: for more information, see https://github.com/rust-lang/rust/issues/43122
= help: add `#![feature(generators)]` to the crate attributes to enable

error[E0658]: yield syntax is experimental
--> $DIR/feature-gate-generators.rs:8:5
|
LL | yield;
| ^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/43122
= help: add `#![feature(generators)]` to the crate attributes to enable

error[E0658]: yield syntax is experimental
--> $DIR/feature-gate-generators.rs:9:5
|
LL | yield 0;
| ^^^^^^^
|
= note: for more information, see https://github.com/rust-lang/rust/issues/43122
= help: add `#![feature(generators)]` to the crate attributes to enable

error[E0627]: yield statement outside of generator literal
--> $DIR/feature-gate-generators.rs:2:5
|
LL | yield true;
| ^^^^^^^^^^

error: aborting due to 2 previous errors
error: aborting due to 4 previous errors

For more information about this error, try `rustc --explain E0658`.

0 comments on commit 1ac66dd

Please sign in to comment.