about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2017-08-14 19:36:13 -0700
committerAlex Crichton <alex@alexcrichton.com>2017-08-14 19:36:13 -0700
commit1413253a41de87ce7da73f0733aa3f433b1f5a3b (patch)
tree111cba46a53aaaa0733b6b8ba19aece25b6f8533 /src/libsyntax
parentb045c201b2086073f43d76290b9cb2a5a8e16f89 (diff)
parent56fe3b2ad0055bb28325f412395577e2b842719a (diff)
downloadrust-1413253a41de87ce7da73f0733aa3f433b1f5a3b.tar.gz
rust-1413253a41de87ce7da73f0733aa3f433b1f5a3b.zip
Merge remote-tracking branch 'origin/master' into gen
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs6
-rw-r--r--src/libsyntax/attr.rs2
-rw-r--r--src/libsyntax/codemap.rs4
-rw-r--r--src/libsyntax/ext/base.rs16
-rw-r--r--src/libsyntax/ext/derive.rs1
-rw-r--r--src/libsyntax/ext/expand.rs27
-rw-r--r--src/libsyntax/ext/source_util.rs11
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs12
-rw-r--r--src/libsyntax/feature_gate.rs28
-rw-r--r--src/libsyntax/parse/mod.rs2
-rw-r--r--src/libsyntax/parse/parser.rs2
-rw-r--r--src/libsyntax/std_inject.rs1
-rw-r--r--src/libsyntax/test.rs1
13 files changed, 85 insertions, 28 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index cce428cad6d..14578179b43 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -563,8 +563,8 @@ pub enum PatKind {
     TupleStruct(Path, Vec<P<Pat>>, Option<usize>),
 
     /// A possibly qualified path pattern.
-    /// Unquailfied path patterns `A::B::C` can legally refer to variants, structs, constants
-    /// or associated constants. Quailfied path patterns `<A>::B::C`/`<A as Trait>::B::C` can
+    /// Unqualified path patterns `A::B::C` can legally refer to variants, structs, constants
+    /// or associated constants. Qualified path patterns `<A>::B::C`/`<A as Trait>::B::C` can
     /// only legally refer to associated constants.
     Path(Option<QSelf>, Path),
 
@@ -1841,7 +1841,7 @@ pub struct Item {
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum ItemKind {
-    /// An`extern crate` item, with optional original crate name.
+    /// An `extern crate` item, with optional original crate name.
     ///
     /// E.g. `extern crate foo` or `extern crate foo_bar as foo`
     ExternCrate(Option<Name>),
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index a247fe7f8a5..d5caf458fd7 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -435,7 +435,7 @@ pub fn mk_attr_inner(span: Span, id: AttrId, item: MetaItem) -> Attribute {
     mk_spanned_attr_inner(span, id, item)
 }
 
-/// Returns an innter attribute with the given value and span.
+/// Returns an inner attribute with the given value and span.
 pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute {
     Attribute {
         id: id,
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index bfdcae7641d..6c48b4cadd8 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -761,7 +761,7 @@ mod tests {
     }
 
     /// Given a string like " ~~~~~~~~~~~~ ", produces a span
-    /// coverting that range. The idea is that the string has the same
+    /// converting that range. The idea is that the string has the same
     /// length as the input, and we uncover the byte positions.  Note
     /// that this can span lines and so on.
     fn span_from_selection(input: &str, selection: &str) -> Span {
@@ -771,7 +771,7 @@ mod tests {
         Span { lo: BytePos(left_index), hi: BytePos(right_index + 1), ctxt: NO_EXPANSION }
     }
 
-    /// Test span_to_snippet and span_to_lines for a span coverting 3
+    /// Test span_to_snippet and span_to_lines for a span converting 3
     /// lines in the middle of a file.
     #[test]
     fn span_to_snippet_and_lines_spanning_multiple_lines() {
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 194d30e25d4..72b2552f64f 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -532,10 +532,16 @@ pub enum SyntaxExtension {
     /// A normal, function-like syntax extension.
     ///
     /// `bytes!` is a `NormalTT`.
-    ///
-    /// The `bool` dictates whether the contents of the macro can
-    /// directly use `#[unstable]` things (true == yes).
-    NormalTT(Box<TTMacroExpander>, Option<(ast::NodeId, Span)>, bool),
+    NormalTT {
+        expander: Box<TTMacroExpander>,
+        def_info: Option<(ast::NodeId, Span)>,
+        /// Whether the contents of the macro can
+        /// directly use `#[unstable]` things (true == yes).
+        allow_internal_unstable: bool,
+        /// Whether the contents of the macro can use `unsafe`
+        /// without triggering the `unsafe_code` lint.
+        allow_internal_unsafe: bool,
+    },
 
     /// A function-like syntax extension that has an extra ident before
     /// the block.
@@ -562,7 +568,7 @@ impl SyntaxExtension {
     pub fn kind(&self) -> MacroKind {
         match *self {
             SyntaxExtension::DeclMacro(..) |
-            SyntaxExtension::NormalTT(..) |
+            SyntaxExtension::NormalTT { .. } |
             SyntaxExtension::IdentTT(..) |
             SyntaxExtension::ProcMacro(..) =>
                 MacroKind::Bang,
diff --git a/src/libsyntax/ext/derive.rs b/src/libsyntax/ext/derive.rs
index e7c5d8278d9..38715f7275d 100644
--- a/src/libsyntax/ext/derive.rs
+++ b/src/libsyntax/ext/derive.rs
@@ -64,6 +64,7 @@ pub fn add_derived_markers<T>(cx: &mut ExtCtxt, span: Span, traits: &[ast::Path]
             format: ExpnFormat::MacroAttribute(Symbol::intern(&pretty_name)),
             span: None,
             allow_internal_unstable: true,
+            allow_internal_unsafe: false,
         },
     });
 
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 4843a66a750..9625602fa4a 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -411,6 +411,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 format: MacroAttribute(Symbol::intern(&format!("{}", attr.path))),
                 span: None,
                 allow_internal_unstable: false,
+                allow_internal_unsafe: false,
             }
         });
 
@@ -458,7 +459,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         let path = &mac.node.path;
 
         let ident = ident.unwrap_or_else(|| keywords::Invalid.ident());
-        let validate_and_set_expn_info = |def_site_span, allow_internal_unstable| {
+        let validate_and_set_expn_info = |def_site_span,
+                                          allow_internal_unstable,
+                                          allow_internal_unsafe| {
             if ident.name != keywords::Invalid.name() {
                 return Err(format!("macro {}! expects no ident argument, given '{}'", path, ident));
             }
@@ -467,7 +470,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 callee: NameAndSpan {
                     format: MacroBang(Symbol::intern(&format!("{}", path))),
                     span: def_site_span,
-                    allow_internal_unstable: allow_internal_unstable,
+                    allow_internal_unstable,
+                    allow_internal_unsafe,
                 },
             });
             Ok(())
@@ -476,20 +480,26 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         let opt_expanded = match *ext {
             DeclMacro(ref expand, def_span) => {
                 if let Err(msg) = validate_and_set_expn_info(def_span.map(|(_, s)| s),
-                                                             false) {
+                                                             false, false) {
                     self.cx.span_err(path.span, &msg);
                     return kind.dummy(span);
                 }
                 kind.make_from(expand.expand(self.cx, span, mac.node.stream()))
             }
 
-            NormalTT(ref expandfun, def_info, allow_internal_unstable) => {
+            NormalTT {
+                ref expander,
+                def_info,
+                allow_internal_unstable,
+                allow_internal_unsafe
+            } => {
                 if let Err(msg) = validate_and_set_expn_info(def_info.map(|(_, s)| s),
-                                                             allow_internal_unstable) {
+                                                             allow_internal_unstable,
+                                                             allow_internal_unsafe) {
                     self.cx.span_err(path.span, &msg);
                     return kind.dummy(span);
                 }
-                kind.make_from(expandfun.expand(self.cx, span, mac.node.stream()))
+                kind.make_from(expander.expand(self.cx, span, mac.node.stream()))
             }
 
             IdentTT(ref expander, tt_span, allow_internal_unstable) => {
@@ -504,7 +514,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     callee: NameAndSpan {
                         format: MacroBang(Symbol::intern(&format!("{}", path))),
                         span: tt_span,
-                        allow_internal_unstable: allow_internal_unstable,
+                        allow_internal_unstable,
+                        allow_internal_unsafe: false,
                     }
                 });
 
@@ -540,6 +551,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         span: None,
                         // FIXME probably want to follow macro_rules macros here.
                         allow_internal_unstable: false,
+                        allow_internal_unsafe: false,
                     },
                 });
 
@@ -578,6 +590,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                 format: MacroAttribute(pretty_name),
                 span: None,
                 allow_internal_unstable: false,
+                allow_internal_unsafe: false,
             }
         };
 
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index b293aa8de38..95fe41be122 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -193,13 +193,14 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt, sp: Span, tts: &[tokenstream::Toke
 // resolve a file-system path to an absolute file-system path (if it
 // isn't already)
 fn res_rel_file(cx: &mut ExtCtxt, sp: syntax_pos::Span, arg: &Path) -> PathBuf {
-    // NB: relative paths are resolved relative to the compilation unit
+    // Relative paths are resolved relative to the file in which they are found
+    // after macro expansion (that is, they are unhygienic).
     if !arg.is_absolute() {
         let callsite = sp.source_callsite();
-        let mut cu = PathBuf::from(&cx.codemap().span_to_filename(callsite));
-        cu.pop();
-        cu.push(arg);
-        cu
+        let mut path = PathBuf::from(&cx.codemap().span_to_filename(callsite));
+        path.pop();
+        path.push(arg);
+        path
     } else {
         arg.to_path_buf()
     }
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 80b6794d1e3..7b3fe2bd993 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -269,7 +269,7 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
         valid &= check_lhs_no_empty_seq(sess, &[lhs.clone()])
     }
 
-    let exp: Box<_> = Box::new(MacroRulesMacroExpander {
+    let expander: Box<_> = Box::new(MacroRulesMacroExpander {
         name: def.ident,
         lhses: lhses,
         rhses: rhses,
@@ -278,9 +278,15 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
 
     if body.legacy {
         let allow_internal_unstable = attr::contains_name(&def.attrs, "allow_internal_unstable");
-        NormalTT(exp, Some((def.id, def.span)), allow_internal_unstable)
+        let allow_internal_unsafe = attr::contains_name(&def.attrs, "allow_internal_unsafe");
+        NormalTT {
+            expander,
+            def_info: Some((def.id, def.span)),
+            allow_internal_unstable,
+            allow_internal_unsafe
+        }
     } else {
-        SyntaxExtension::DeclMacro(exp, Some((def.id, def.span)))
+        SyntaxExtension::DeclMacro(expander, Some((def.id, def.span)))
     }
 }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index cb0cc2aafb0..dd64bc3072e 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -194,6 +194,14 @@ declare_features! (
     // rustc internal
     (active, allow_internal_unstable, "1.0.0", None),
 
+    // Allows the use of #[allow_internal_unsafe]. This is an
+    // attribute on macro_rules! and can't use the attribute handling
+    // below (it has to be checked before expansion possibly makes
+    // macros disappear).
+    //
+    // rustc internal
+    (active, allow_internal_unsafe, "1.0.0", None),
+
     // #23121. Array patterns have some hazards yet.
     (active, slice_patterns, "1.0.0", Some(23121)),
 
@@ -368,6 +376,9 @@ declare_features! (
     // global allocators and their internals
     (active, global_allocator, "1.20.0", None),
     (active, allocator_internals, "1.20.0", None),
+
+    // #[doc(cfg(...))]
+    (active, doc_cfg, "1.21.0", Some(43781)),
 );
 
 declare_features! (
@@ -739,6 +750,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                               EXPLAIN_ALLOW_INTERNAL_UNSTABLE,
                                               cfg_fn!(allow_internal_unstable))),
 
+    ("allow_internal_unsafe", Normal, Gated(Stability::Unstable,
+                                            "allow_internal_unsafe",
+                                            EXPLAIN_ALLOW_INTERNAL_UNSAFE,
+                                            cfg_fn!(allow_internal_unsafe))),
+
     ("fundamental", Whitelisted, Gated(Stability::Unstable,
                                        "fundamental",
                                        "the `#[fundamental]` attribute \
@@ -1049,6 +1065,8 @@ pub const EXPLAIN_TRACE_MACROS: &'static str =
     "`trace_macros` is not stable enough for use and is subject to change";
 pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &'static str =
     "allow_internal_unstable side-steps feature gating and stability checks";
+pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &'static str =
+    "allow_internal_unsafe side-steps the unsafe_code lint";
 
 pub const EXPLAIN_CUSTOM_DERIVE: &'static str =
     "`#[derive]` for custom traits is deprecated and will be removed in the future.";
@@ -1161,6 +1179,16 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
             self.context.check_attribute(attr, false);
         }
 
+        if attr.check_name("doc") {
+            if let Some(content) = attr.meta_item_list() {
+                if content.len() == 1 && content[0].check_name("cfg") {
+                    gate_feature_post!(&self, doc_cfg, attr.span,
+                        "#[doc(cfg(...))] is experimental"
+                    );
+                }
+            }
+        }
+
         if self.context.features.proc_macro && attr::is_known(attr) {
             return
         }
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 893bada2670..957164bab79 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -124,7 +124,7 @@ pub fn parse_expr_from_source_str(name: String, source: String, sess: &ParseSess
 
 /// Parses an item.
 ///
-/// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and`Err`
+/// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and `Err`
 /// when a syntax error occurred.
 pub fn parse_item_from_source_str(name: String, source: String, sess: &ParseSess)
                                       -> PResult<Option<P<ast::Item>>> {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index df1bae523a5..245452dcb39 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3595,7 +3595,7 @@ impl<'a> Parser<'a> {
 
     /// Parse a local variable declaration
     fn parse_local(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Local>> {
-        let lo = self.span;
+        let lo = self.prev_span;
         let pat = self.parse_pat()?;
 
         let ty = if self.eat(&token::Colon) {
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index d9ed96f293a..430976e7d3c 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -28,6 +28,7 @@ fn ignored_span(sp: Span) -> Span {
             format: MacroAttribute(Symbol::intern("std_inject")),
             span: None,
             allow_internal_unstable: true,
+            allow_internal_unsafe: false,
         }
     });
     Span { ctxt: SyntaxContext::empty().apply_mark(mark), ..sp }
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 887479a2472..c05e166e013 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -291,6 +291,7 @@ fn generate_test_harness(sess: &ParseSess,
             format: MacroAttribute(Symbol::intern("test")),
             span: None,
             allow_internal_unstable: true,
+            allow_internal_unsafe: false,
         }
     });