提交 b325e4f2 编写于 作者: F Felix S. Klock II

Add feature-gates for desugaring-based `box` and placement-`in`.

update test/compile-fail/feature-gate-box-expr.rs to reflect new feature gates.

Part of what lands with Issue 22181.
上级 d79bbbc4
......@@ -82,8 +82,10 @@
#![feature(no_std)]
#![feature(nonzero)]
#![feature(optin_builtin_traits)]
#![feature(placement_in_syntax)]
#![feature(raw)]
#![feature(staged_api)]
#![feature(placement_in_syntax)]
#![feature(unboxed_closures)]
#![feature(unique)]
#![feature(unsafe_no_drop_flag, filling_drop)]
......
......@@ -234,6 +234,7 @@
#![feature(no_std)]
#![feature(oom)]
#![feature(optin_builtin_traits)]
#![feature(placement_in_syntax)]
#![feature(rand)]
#![feature(raw)]
#![feature(reflect_marker)]
......
......@@ -56,6 +56,7 @@ fn push_compiler_expansion(fld: &mut MacroExpander, span: Span, expansion_desc:
});
}
let expr_span = e.span;
return e.and_then(|ast::Expr {id, node, span}| match node {
// expr_mac should really be expr_ext or something; it's the
......@@ -94,6 +95,12 @@ fn push_compiler_expansion(fld: &mut MacroExpander, span: Span, expansion_desc:
// InPlace::finalize(place)
// })
// Ensure feature-gate is enabled
feature_gate::check_for_placement_in(
fld.cx.ecfg.features,
&fld.cx.parse_sess.span_diagnostic,
expr_span);
let value_span = value_expr.span;
let placer_span = placer.span;
......
......@@ -80,6 +80,7 @@
("visible_private_types", "1.0.0", Active),
("slicing_syntax", "1.0.0", Accepted),
("box_syntax", "1.0.0", Active),
("placement_in_syntax", "1.0.0", Active),
("pushpop_unsafe", "1.2.0", Active),
("on_unimplemented", "1.0.0", Active),
("simd_ffi", "1.0.0", Active),
......@@ -326,6 +327,8 @@ pub struct Features {
pub allow_trace_macros: bool,
pub allow_internal_unstable: bool,
pub allow_custom_derive: bool,
pub allow_placement_in: bool,
pub allow_box: bool,
pub allow_pushpop_unsafe: bool,
pub simd_ffi: bool,
pub unmarked_api: bool,
......@@ -350,6 +353,8 @@ pub fn new() -> Features {
allow_trace_macros: false,
allow_internal_unstable: false,
allow_custom_derive: false,
allow_placement_in: false,
allow_box: false,
allow_pushpop_unsafe: false,
simd_ffi: false,
unmarked_api: false,
......@@ -361,6 +366,29 @@ pub fn new() -> Features {
}
}
const EXPLAIN_BOX_SYNTAX: &'static str =
"box expression syntax is experimental; you can call `Box::new` instead.";
const EXPLAIN_PLACEMENT_IN: &'static str =
"placement-in expression syntax is experimental and subject to change.";
const EXPLAIN_PUSHPOP_UNSAFE: &'static str =
"push/pop_unsafe macros are experimental and subject to change.";
pub fn check_for_box_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) {
if let Some(&Features { allow_box: true, .. }) = f {
return;
}
emit_feature_err(diag, "box_syntax", span, EXPLAIN_BOX_SYNTAX);
}
pub fn check_for_placement_in(f: Option<&Features>, diag: &SpanHandler, span: Span) {
if let Some(&Features { allow_placement_in: true, .. }) = f {
return;
}
emit_feature_err(diag, "placement_in_syntax", span, EXPLAIN_PLACEMENT_IN);
}
pub fn check_for_pushpop_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) {
if let Some(&Features { allow_pushpop_unsafe: true, .. }) = f {
return;
......@@ -376,6 +404,11 @@ struct Context<'a> {
}
impl<'a> Context<'a> {
fn enable_feature(&mut self, feature: &'static str) {
debug!("enabling feature: {}", feature);
self.features.push(feature);
}
fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
let has_feature = self.has_feature(feature);
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature);
......@@ -498,6 +531,26 @@ fn visit_mac(&mut self, mac: &ast::Mac) {
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
self.context.check_attribute(attr, true);
}
fn visit_expr(&mut self, e: &ast::Expr) {
// Issue 22181: overloaded-`box` and placement-`in` are
// implemented via a desugaring expansion, so their feature
// gates go into MacroVisitor since that works pre-expansion.
//
// Issue 22234: we also check during expansion as well.
// But we keep these checks as a pre-expansion check to catch
// uses in e.g. conditionalized code.
if let ast::ExprBox(None, _) = e.node {
self.context.gate_feature("box_syntax", e.span, EXPLAIN_BOX_SYNTAX);
}
if let ast::ExprBox(Some(_), _) = e.node {
self.context.gate_feature("placement_in_syntax", e.span, EXPLAIN_PLACEMENT_IN);
}
visit::walk_expr(self, e);
}
}
struct PostExpansionVisitor<'a> {
......@@ -764,7 +817,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
match KNOWN_FEATURES.iter()
.find(|& &(n, _, _)| name == n) {
Some(&(name, _, Active)) => {
cx.features.push(name);
cx.enable_feature(name);
}
Some(&(_, _, Removed)) => {
span_handler.span_err(mi.span, "feature has been removed");
......@@ -797,6 +850,8 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
allow_trace_macros: cx.has_feature("trace_macros"),
allow_internal_unstable: cx.has_feature("allow_internal_unstable"),
allow_custom_derive: cx.has_feature("custom_derive"),
allow_placement_in: cx.has_feature("placement_in_syntax"),
allow_box: cx.has_feature("box_syntax"),
allow_pushpop_unsafe: cx.has_feature("pushpop_unsafe"),
simd_ffi: cx.has_feature("simd_ffi"),
unmarked_api: cx.has_feature("unmarked_api"),
......
......@@ -17,6 +17,9 @@ fn main() {
let x = box () 'c'; //~ ERROR box expression syntax is experimental
println!("x: {}", x);
let x = box (HEAP) 'c'; //~ ERROR box expression syntax is experimental
let x = box (HEAP) 'c'; //~ ERROR placement-in expression syntax is experimental
println!("x: {}", x);
let x = in HEAP { 'c' }; //~ ERROR placement-in expression syntax is experimental
println!("x: {}", x);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册