From 52bdda778ad595e661d06b16a193b3affe443d41 Mon Sep 17 00:00:00 2001
From: "Felix S. Klock II" <pnkfelix@pnkfx.org>
Date: Sun, 15 Feb 2015 22:14:03 +0100
Subject: [PATCH] Address the `asm!` case of #22234.

---
 src/libsyntax/ext/asm.rs            |  7 +++++++
 src/libsyntax/ext/expand.rs         |  9 ++++++++-
 src/libsyntax/feature_gate.rs       | 15 ++++++++++-----
 src/test/compile-fail/asm-gated2.rs | 15 +++++++++++++++
 4 files changed, 40 insertions(+), 6 deletions(-)
 create mode 100644 src/test/compile-fail/asm-gated2.rs

diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs
index 1ceda2e08dd..d8cba139fb5 100644
--- a/src/libsyntax/ext/asm.rs
+++ b/src/libsyntax/ext/asm.rs
@@ -18,6 +18,7 @@ use codemap;
 use codemap::Span;
 use ext::base;
 use ext::base::*;
+use feature_gate;
 use parse::token::InternedString;
 use parse::token;
 use ptr::P;
@@ -48,6 +49,12 @@ static OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                        -> Box<base::MacResult+'cx> {
+    if !cx.ecfg.enable_asm() {
+        feature_gate::emit_feature_err(
+            &cx.parse_sess.span_diagnostic, "asm", sp, feature_gate::EXPLAIN_ASM);
+        return DummyResult::expr(sp);
+    }
+
     let mut p = cx.new_parser_from_tts(tts);
     let mut asm = InternedString::new("");
     let mut asm_str_style = None;
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 267d732c9e6..e31c1a32749 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -1425,7 +1425,14 @@ impl<'feat> ExpansionConfig<'feat> {
 
     pub fn enable_quotes(&self) -> bool {
         match self.features {
-            Some(&Features { quote: true, .. }) => true,
+            Some(&Features { allow_quote: true, .. }) => true,
+            _ => false,
+        }
+    }
+
+    pub fn enable_asm(&self) -> bool {
+        match self.features {
+            Some(&Features { allow_asm: true, .. }) => true,
             _ => false,
         }
     }
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index ca7ae32f09e..9d14f894a46 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -156,7 +156,8 @@ pub struct Features {
     pub unboxed_closures: bool,
     pub rustc_diagnostic_macros: bool,
     pub visible_private_types: bool,
-    pub quote: bool,
+    pub allow_quote: bool,
+    pub allow_asm: bool,
     pub old_orphan_check: bool,
     pub simd_ffi: bool,
     pub unmarked_api: bool,
@@ -172,7 +173,8 @@ impl Features {
             unboxed_closures: false,
             rustc_diagnostic_macros: false,
             visible_private_types: false,
-            quote: false,
+            allow_quote: false,
+            allow_asm: false,
             old_orphan_check: false,
             simd_ffi: false,
             unmarked_api: false,
@@ -221,6 +223,9 @@ pub fn emit_feature_warn(diag: &SpanHandler, feature: &str, span: Span, explain:
     }
 }
 
+pub const EXPLAIN_ASM: &'static str =
+    "inline assembly is not stable enough for use and is subject to change";
+
 struct MacroVisitor<'a> {
     context: &'a Context<'a>
 }
@@ -231,8 +236,7 @@ impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
         let id = path.segments.last().unwrap().identifier;
 
         if id == token::str_to_ident("asm") {
-            self.context.gate_feature("asm", path.span, "inline assembly is not \
-                stable enough for use and is subject to change");
+            self.context.gate_feature("asm", path.span, EXPLAIN_ASM);
         }
 
         else if id == token::str_to_ident("log_syntax") {
@@ -594,7 +598,8 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
         unboxed_closures: cx.has_feature("unboxed_closures"),
         rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
         visible_private_types: cx.has_feature("visible_private_types"),
-        quote: cx.has_feature("quote"),
+        allow_quote: cx.has_feature("quote"),
+        allow_asm: cx.has_feature("asm"),
         old_orphan_check: cx.has_feature("old_orphan_check"),
         simd_ffi: cx.has_feature("simd_ffi"),
         unmarked_api: cx.has_feature("unmarked_api"),
diff --git a/src/test/compile-fail/asm-gated2.rs b/src/test/compile-fail/asm-gated2.rs
new file mode 100644
index 00000000000..d2ee01109f8
--- /dev/null
+++ b/src/test/compile-fail/asm-gated2.rs
@@ -0,0 +1,15 @@
+// Copyright 2015 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.
+
+fn main() {
+    unsafe {
+        println!("{}", asm!("")); //~ ERROR inline assembly is not stable
+    }
+}