Skip to content

Commit e9bd2c9

Browse files
committed
---
yaml --- r: 235727 b: refs/heads/stable c: b325e4f h: refs/heads/master i: 235725: 5c09fb2 235723: aad611b 235719: c3a9b2d 235711: ebfa0a7 v: v3
1 parent c509a98 commit e9bd2c9

File tree

6 files changed

+71
-3
lines changed

6 files changed

+71
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/heads/tmp: afae2ff723393b3ab4ccffef6ac7c6d1809e2da0
2929
refs/tags/1.0.0-alpha.2: 4c705f6bc559886632d3871b04f58aab093bfa2f
3030
refs/tags/homu-tmp: f859507de8c410b648d934d8f5ec1c52daac971d
3131
refs/tags/1.0.0-beta: 8cbb92b53468ee2b0c2d3eeb8567005953d40828
32-
refs/heads/stable: d79bbbc4ef20a11680a004b600a90281e4c5e04a
32+
refs/heads/stable: b325e4f28e0735bb951bdf9f1db1206bd3ee715b
3333
refs/tags/1.0.0: 55bd4f8ff2b323f317ae89e254ce87162d52a375
3434
refs/tags/1.1.0: bc3c16f09287e5545c1d3f76b7abd54f2eca868b
3535
refs/tags/1.2.0: f557861f822c34f07270347b94b5280de20a597e

branches/stable/src/liballoc/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@
8282
#![feature(no_std)]
8383
#![feature(nonzero)]
8484
#![feature(optin_builtin_traits)]
85+
#![feature(placement_in_syntax)]
8586
#![feature(raw)]
8687
#![feature(staged_api)]
88+
#![feature(placement_in_syntax)]
8789
#![feature(unboxed_closures)]
8890
#![feature(unique)]
8991
#![feature(unsafe_no_drop_flag, filling_drop)]

branches/stable/src/libstd/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@
234234
#![feature(no_std)]
235235
#![feature(oom)]
236236
#![feature(optin_builtin_traits)]
237+
#![feature(placement_in_syntax)]
237238
#![feature(rand)]
238239
#![feature(raw)]
239240
#![feature(reflect_marker)]

branches/stable/src/libsyntax/ext/expand.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
5656
});
5757
}
5858

59+
let expr_span = e.span;
5960
return e.and_then(|ast::Expr {id, node, span}| match node {
6061

6162
// expr_mac should really be expr_ext or something; it's the
@@ -94,6 +95,12 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
9495
// InPlace::finalize(place)
9596
// })
9697

98+
// Ensure feature-gate is enabled
99+
feature_gate::check_for_placement_in(
100+
fld.cx.ecfg.features,
101+
&fld.cx.parse_sess.span_diagnostic,
102+
expr_span);
103+
97104
let value_span = value_expr.span;
98105
let placer_span = placer.span;
99106

branches/stable/src/libsyntax/feature_gate.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
8080
("visible_private_types", "1.0.0", Active),
8181
("slicing_syntax", "1.0.0", Accepted),
8282
("box_syntax", "1.0.0", Active),
83+
("placement_in_syntax", "1.0.0", Active),
8384
("pushpop_unsafe", "1.2.0", Active),
8485
("on_unimplemented", "1.0.0", Active),
8586
("simd_ffi", "1.0.0", Active),
@@ -326,6 +327,8 @@ pub struct Features {
326327
pub allow_trace_macros: bool,
327328
pub allow_internal_unstable: bool,
328329
pub allow_custom_derive: bool,
330+
pub allow_placement_in: bool,
331+
pub allow_box: bool,
329332
pub allow_pushpop_unsafe: bool,
330333
pub simd_ffi: bool,
331334
pub unmarked_api: bool,
@@ -350,6 +353,8 @@ impl Features {
350353
allow_trace_macros: false,
351354
allow_internal_unstable: false,
352355
allow_custom_derive: false,
356+
allow_placement_in: false,
357+
allow_box: false,
353358
allow_pushpop_unsafe: false,
354359
simd_ffi: false,
355360
unmarked_api: false,
@@ -361,6 +366,29 @@ impl Features {
361366
}
362367
}
363368

369+
const EXPLAIN_BOX_SYNTAX: &'static str =
370+
"box expression syntax is experimental; you can call `Box::new` instead.";
371+
372+
const EXPLAIN_PLACEMENT_IN: &'static str =
373+
"placement-in expression syntax is experimental and subject to change.";
374+
375+
const EXPLAIN_PUSHPOP_UNSAFE: &'static str =
376+
"push/pop_unsafe macros are experimental and subject to change.";
377+
378+
pub fn check_for_box_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) {
379+
if let Some(&Features { allow_box: true, .. }) = f {
380+
return;
381+
}
382+
emit_feature_err(diag, "box_syntax", span, EXPLAIN_BOX_SYNTAX);
383+
}
384+
385+
pub fn check_for_placement_in(f: Option<&Features>, diag: &SpanHandler, span: Span) {
386+
if let Some(&Features { allow_placement_in: true, .. }) = f {
387+
return;
388+
}
389+
emit_feature_err(diag, "placement_in_syntax", span, EXPLAIN_PLACEMENT_IN);
390+
}
391+
364392
pub fn check_for_pushpop_syntax(f: Option<&Features>, diag: &SpanHandler, span: Span) {
365393
if let Some(&Features { allow_pushpop_unsafe: true, .. }) = f {
366394
return;
@@ -376,6 +404,11 @@ struct Context<'a> {
376404
}
377405

378406
impl<'a> Context<'a> {
407+
fn enable_feature(&mut self, feature: &'static str) {
408+
debug!("enabling feature: {}", feature);
409+
self.features.push(feature);
410+
}
411+
379412
fn gate_feature(&self, feature: &str, span: Span, explain: &str) {
380413
let has_feature = self.has_feature(feature);
381414
debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", feature, span, has_feature);
@@ -498,6 +531,26 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
498531
fn visit_attribute(&mut self, attr: &'v ast::Attribute) {
499532
self.context.check_attribute(attr, true);
500533
}
534+
535+
fn visit_expr(&mut self, e: &ast::Expr) {
536+
// Issue 22181: overloaded-`box` and placement-`in` are
537+
// implemented via a desugaring expansion, so their feature
538+
// gates go into MacroVisitor since that works pre-expansion.
539+
//
540+
// Issue 22234: we also check during expansion as well.
541+
// But we keep these checks as a pre-expansion check to catch
542+
// uses in e.g. conditionalized code.
543+
544+
if let ast::ExprBox(None, _) = e.node {
545+
self.context.gate_feature("box_syntax", e.span, EXPLAIN_BOX_SYNTAX);
546+
}
547+
548+
if let ast::ExprBox(Some(_), _) = e.node {
549+
self.context.gate_feature("placement_in_syntax", e.span, EXPLAIN_PLACEMENT_IN);
550+
}
551+
552+
visit::walk_expr(self, e);
553+
}
501554
}
502555

503556
struct PostExpansionVisitor<'a> {
@@ -764,7 +817,7 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
764817
match KNOWN_FEATURES.iter()
765818
.find(|& &(n, _, _)| name == n) {
766819
Some(&(name, _, Active)) => {
767-
cx.features.push(name);
820+
cx.enable_feature(name);
768821
}
769822
Some(&(_, _, Removed)) => {
770823
span_handler.span_err(mi.span, "feature has been removed");
@@ -797,6 +850,8 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler,
797850
allow_trace_macros: cx.has_feature("trace_macros"),
798851
allow_internal_unstable: cx.has_feature("allow_internal_unstable"),
799852
allow_custom_derive: cx.has_feature("custom_derive"),
853+
allow_placement_in: cx.has_feature("placement_in_syntax"),
854+
allow_box: cx.has_feature("box_syntax"),
800855
allow_pushpop_unsafe: cx.has_feature("pushpop_unsafe"),
801856
simd_ffi: cx.has_feature("simd_ffi"),
802857
unmarked_api: cx.has_feature("unmarked_api"),

branches/stable/src/test/compile-fail/feature-gate-box-expr.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ fn main() {
1717
let x = box () 'c'; //~ ERROR box expression syntax is experimental
1818
println!("x: {}", x);
1919

20-
let x = box (HEAP) 'c'; //~ ERROR box expression syntax is experimental
20+
let x = box (HEAP) 'c'; //~ ERROR placement-in expression syntax is experimental
21+
println!("x: {}", x);
22+
23+
let x = in HEAP { 'c' }; //~ ERROR placement-in expression syntax is experimental
2124
println!("x: {}", x);
2225
}

0 commit comments

Comments
 (0)