]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #20482: kmcallister/macro-reform
authorAlex Crichton <alex@alexcrichton.com>
Tue, 6 Jan 2015 03:01:17 +0000 (19:01 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 6 Jan 2015 03:01:17 +0000 (19:01 -0800)
Conflicts:
src/libflate/lib.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libsyntax/feature_gate.rs
src/libsyntax/parse/parser.rs
src/libsyntax/show_span.rs
src/test/auxiliary/macro_crate_test.rs
src/test/compile-fail/lint-stability.rs
src/test/run-pass/intrinsics-math.rs
src/test/run-pass/tcp-connect-timeouts.rs

320 files changed:
src/compiletest/compiletest.rs
src/doc/guide-macros.md
src/doc/guide-plugin.md
src/doc/reference.md
src/etc/vim/syntax/rust.vim
src/grammar/verify.rs
src/liballoc/lib.rs
src/libcollections/lib.rs
src/libcollections/macros.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcore/fmt/mod.rs
src/libcore/lib.rs
src/libcore/macros.rs
src/libcore/num/float_macros.rs
src/libcore/num/int_macros.rs
src/libcore/num/uint_macros.rs
src/libcore/result.rs
src/libcore/str/mod.rs
src/libcoretest/lib.rs
src/libcoretest/num/int_macros.rs
src/libcoretest/num/mod.rs
src/libcoretest/num/uint_macros.rs
src/libflate/lib.rs
src/libfmt_macros/lib.rs
src/libgetopts/lib.rs
src/liblog/lib.rs
src/liblog/macros.rs
src/librand/distributions/mod.rs
src/librand/distributions/range.rs
src/librand/isaac.rs
src/librand/lib.rs
src/librbml/lib.rs
src/libregex/lib.rs
src/librustc/lib.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/ty.rs
src/librustc/plugin/load.rs
src/librustc/plugin/mod.rs
src/librustc/plugin/registry.rs
src/librustc_back/lib.rs
src/librustc_back/sha2.rs
src/librustc_back/svh.rs
src/librustc_back/target/mod.rs
src/librustc_borrowck/borrowck/mod.rs
src/librustc_borrowck/lib.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/librustc_resolve/lib.rs
src/librustc_trans/lib.rs
src/librustc_trans/trans/context.rs
src/librustc_trans/trans/macros.rs
src/librustc_trans/trans/mod.rs
src/librustc_typeck/lib.rs
src/librustdoc/html/highlight.rs
src/librustdoc/lib.rs
src/librustdoc/visit_ast.rs
src/libserialize/lib.rs
src/libstd/bitflags.rs
src/libstd/collections/hash/set.rs
src/libstd/io/buffered.rs
src/libstd/io/mod.rs
src/libstd/io/test.rs
src/libstd/lib.rs
src/libstd/macros.rs
src/libstd/macros_stage0.rs [new file with mode: 0644]
src/libstd/num/float_macros.rs
src/libstd/num/int_macros.rs
src/libstd/num/uint_macros.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/rand/os.rs
src/libstd/rt/macros.rs
src/libstd/rt/mod.rs
src/libstd/thread_local/mod.rs
src/libstd/thread_local/scoped.rs
src/libstd/time/duration.rs
src/libsyntax/ast.rs
src/libsyntax/diagnostics/macros.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/deriving/cmp/eq.rs
src/libsyntax/ext/deriving/cmp/ord.rs
src/libsyntax/ext/deriving/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax/ext/tt/transcribe.rs
src/libsyntax/feature_gate.rs
src/libsyntax/fold.rs
src/libsyntax/lib.rs
src/libsyntax/parse/mod.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/std_inject.rs
src/libsyntax/visit.rs
src/libterm/lib.rs
src/libterm/terminfo/parser/compiled.rs
src/libtest/lib.rs
src/test/auxiliary/issue-13560-3.rs
src/test/auxiliary/lint_group_plugin_test.rs
src/test/auxiliary/lint_plugin_test.rs
src/test/auxiliary/lint_stability.rs
src/test/auxiliary/logging_right_crate.rs
src/test/auxiliary/macro_crate_MacroRulesTT.rs [new file with mode: 0644]
src/test/auxiliary/macro_crate_def_only.rs
src/test/auxiliary/macro_crate_nonterminal.rs [new file with mode: 0644]
src/test/auxiliary/macro_crate_test.rs
src/test/auxiliary/macro_export_inner_module.rs
src/test/auxiliary/macro_non_reexport_2.rs [new file with mode: 0644]
src/test/auxiliary/macro_reexport_1.rs [new file with mode: 0644]
src/test/auxiliary/macro_reexport_2.rs [new file with mode: 0644]
src/test/auxiliary/macro_reexport_2_no_use.rs [new file with mode: 0644]
src/test/auxiliary/plugin_args.rs [new file with mode: 0644]
src/test/auxiliary/svh-a-base.rs
src/test/auxiliary/svh-a-change-lit.rs
src/test/auxiliary/svh-a-change-significant-cfg.rs
src/test/auxiliary/svh-a-change-trait-bound.rs
src/test/auxiliary/svh-a-change-type-arg.rs
src/test/auxiliary/svh-a-change-type-ret.rs
src/test/auxiliary/svh-a-change-type-static.rs
src/test/auxiliary/svh-a-comment.rs
src/test/auxiliary/svh-a-doc.rs
src/test/auxiliary/svh-a-macro.rs
src/test/auxiliary/svh-a-no-change.rs
src/test/auxiliary/svh-a-redundant-cfg.rs
src/test/auxiliary/svh-a-whitespace.rs
src/test/auxiliary/two_macros.rs [new file with mode: 0644]
src/test/auxiliary/weak-lang-items.rs
src/test/bench/core-std.rs
src/test/bench/shootout-mandelbrot.rs
src/test/bench/shootout-regex-dna.rs
src/test/compile-fail-fulldeps/gated-phase.rs [deleted file]
src/test/compile-fail-fulldeps/gated-plugin.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/lint-group-plugin-deny-cmdline.rs
src/test/compile-fail-fulldeps/lint-plugin-deny-attr.rs
src/test/compile-fail-fulldeps/lint-plugin-deny-cmdline.rs
src/test/compile-fail-fulldeps/lint-plugin-forbid-attrs.rs
src/test/compile-fail-fulldeps/lint-plugin-forbid-cmdline.rs
src/test/compile-fail-fulldeps/macro-crate-cannot-read-embedded-ident.rs
src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs [new file with mode: 0644]
src/test/compile-fail-fulldeps/macro-crate-rlib.rs
src/test/compile-fail-fulldeps/macro-crate-unexported-macro.rs
src/test/compile-fail-fulldeps/macro-crate-unknown-crate.rs
src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs [deleted file]
src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs [new file with mode: 0644]
src/test/compile-fail/asm-src-loc-codegen-units.rs
src/test/compile-fail/cleanup-rvalue-scopes-cf.rs
src/test/compile-fail/const-block-non-item-statement.rs
src/test/compile-fail/deprecated-phase.rs [new file with mode: 0644]
src/test/compile-fail/empty-macro-use.rs [new file with mode: 0644]
src/test/compile-fail/fail-no-dead-code-core.rs
src/test/compile-fail/gated-macro-rules.rs [deleted file]
src/test/compile-fail/hygienic-label-1.rs
src/test/compile-fail/hygienic-label-2.rs
src/test/compile-fail/hygienic-label-3.rs
src/test/compile-fail/hygienic-label-4.rs
src/test/compile-fail/if-let.rs
src/test/compile-fail/infinite-macro-expansion.rs
src/test/compile-fail/issue-10536.rs
src/test/compile-fail/issue-15167.rs
src/test/compile-fail/issue-16098.rs
src/test/compile-fail/issue-6596.rs
src/test/compile-fail/lint-stability.rs
src/test/compile-fail/lint-unsafe-block.rs
src/test/compile-fail/liveness-return-last-stmt-semi.rs
src/test/compile-fail/macro-crate-nonterminal-non-root.rs [new file with mode: 0644]
src/test/compile-fail/macro-incomplete-parse.rs
src/test/compile-fail/macro-inner-attributes.rs
src/test/compile-fail/macro-keyword.rs [new file with mode: 0644]
src/test/compile-fail/macro-match-nonterminal.rs
src/test/compile-fail/macro-no-implicit-reexport.rs [new file with mode: 0644]
src/test/compile-fail/macro-outer-attributes.rs
src/test/compile-fail/macro-reexport-malformed-1.rs [new file with mode: 0644]
src/test/compile-fail/macro-reexport-malformed-2.rs [new file with mode: 0644]
src/test/compile-fail/macro-reexport-malformed-3.rs [new file with mode: 0644]
src/test/compile-fail/macro-reexport-not-locally-visible.rs [new file with mode: 0644]
src/test/compile-fail/macro-use-bad-args-1.rs [new file with mode: 0644]
src/test/compile-fail/macro-use-bad-args-2.rs [new file with mode: 0644]
src/test/compile-fail/macro-use-wrong-name.rs [new file with mode: 0644]
src/test/compile-fail/macros-no-semicolon-items.rs
src/test/compile-fail/method-macro-backtrace.rs
src/test/compile-fail/missing-macro-use.rs [new file with mode: 0644]
src/test/compile-fail/module-macro_use-arguments.rs [new file with mode: 0644]
src/test/compile-fail/multi-plugin-attr.rs [new file with mode: 0644]
src/test/compile-fail/no-link.rs [new file with mode: 0644]
src/test/compile-fail/pattern-macro-hygiene.rs
src/test/compile-fail/recursion_limit.rs
src/test/compile-fail/svh-change-lit.rs
src/test/compile-fail/svh-change-significant-cfg.rs
src/test/compile-fail/svh-change-trait-bound.rs
src/test/compile-fail/svh-change-type-arg.rs
src/test/compile-fail/svh-change-type-ret.rs
src/test/compile-fail/svh-change-type-static.rs
src/test/compile-fail/trace_macros-format.rs
src/test/compile-fail/while-let.rs
src/test/debuginfo/lexical-scope-with-macro.rs
src/test/pretty/issue-4264.pp
src/test/run-fail/rt-set-exit-status-panic.rs
src/test/run-fail/rt-set-exit-status-panic2.rs
src/test/run-fail/rt-set-exit-status.rs
src/test/run-make/extern-diff-internal-name/test.rs
src/test/run-make/lto-syntax-extension/main.rs
src/test/run-make/pretty-expanded-hygiene/input.pp.rs
src/test/run-make/pretty-expanded-hygiene/input.rs
src/test/run-pass-fulldeps/issue_16723_multiple_items_syntax_ext.rs
src/test/run-pass-fulldeps/lint-group-plugin.rs
src/test/run-pass-fulldeps/lint-plugin-cmdline.rs
src/test/run-pass-fulldeps/lint-plugin.rs
src/test/run-pass-fulldeps/macro-crate-does-hygiene-work.rs
src/test/run-pass-fulldeps/macro-crate-outlive-expansion-phase.rs
src/test/run-pass-fulldeps/macro-crate.rs
src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs [deleted file]
src/test/run-pass-fulldeps/plugin-link-does-resolve.rs [new file with mode: 0644]
src/test/run-pass-fulldeps/roman-numerals-macro.rs
src/test/run-pass-fulldeps/syntax-extension-with-dll-deps.rs
src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
src/test/run-pass/capturing-logging.rs
src/test/run-pass/cfg-macros-foo.rs
src/test/run-pass/cfg-macros-notfoo.rs
src/test/run-pass/cleanup-rvalue-for-scope.rs
src/test/run-pass/cleanup-rvalue-scopes.rs
src/test/run-pass/colorful-write-macros.rs
src/test/run-pass/conditional-debug-macro-off.rs
src/test/run-pass/const-binops.rs
src/test/run-pass/const-block-item-macro-codegen.rs
src/test/run-pass/const-block-item.rs
src/test/run-pass/core-run-destroy.rs
src/test/run-pass/crate-leading-sep.rs [new file with mode: 0644]
src/test/run-pass/deprecated-macro_escape-inner.rs [new file with mode: 0644]
src/test/run-pass/deprecated-macro_escape.rs [new file with mode: 0644]
src/test/run-pass/deprecated-phase-syntax.rs [deleted file]
src/test/run-pass/deriving-in-macro.rs
src/test/run-pass/deriving-show.rs
src/test/run-pass/enum-discrim-width-stuff.rs
src/test/run-pass/exponential-notation.rs
src/test/run-pass/html-literals.rs
src/test/run-pass/hygienic-labels-in-let.rs
src/test/run-pass/hygienic-labels.rs
src/test/run-pass/ifmt.rs
src/test/run-pass/intrinsics-math.rs
src/test/run-pass/issue-14330.rs
src/test/run-pass/issue-14936.rs
src/test/run-pass/issue-15189.rs
src/test/run-pass/issue-15221.rs
src/test/run-pass/issue-5060.rs
src/test/run-pass/issue-5554.rs
src/test/run-pass/issue-5718.rs
src/test/run-pass/issue-7911.rs
src/test/run-pass/issue-8709.rs
src/test/run-pass/issue-8851.rs
src/test/run-pass/issue-9110.rs
src/test/run-pass/issue-9129.rs
src/test/run-pass/issue-9737.rs
src/test/run-pass/lambda-var-hygiene.rs
src/test/run-pass/let-var-hygiene.rs
src/test/run-pass/logging-enabled-debug.rs
src/test/run-pass/logging-enabled.rs
src/test/run-pass/logging-separate-lines.rs
src/test/run-pass/macro-2.rs
src/test/run-pass/macro-attribute-expansion.rs
src/test/run-pass/macro-attributes.rs
src/test/run-pass/macro-block-nonterminal.rs
src/test/run-pass/macro-crate-def-only.rs
src/test/run-pass/macro-crate-nonterminal-renamed.rs [new file with mode: 0644]
src/test/run-pass/macro-crate-nonterminal.rs [new file with mode: 0644]
src/test/run-pass/macro-crate-use.rs [new file with mode: 0644]
src/test/run-pass/macro-deep_expansion.rs
src/test/run-pass/macro-export-inner-module.rs
src/test/run-pass/macro-interpolation.rs
src/test/run-pass/macro-invocation-in-count-expr-fixed-array-type.rs
src/test/run-pass/macro-meta-items.rs
src/test/run-pass/macro-method-issue-4621.rs
src/test/run-pass/macro-multiple-items.rs
src/test/run-pass/macro-nt-list.rs
src/test/run-pass/macro-of-higher-order.rs
src/test/run-pass/macro-pat.rs
src/test/run-pass/macro-path.rs
src/test/run-pass/macro-reexport-no-intermediate-use.rs [new file with mode: 0644]
src/test/run-pass/macro-reexport.rs [new file with mode: 0644]
src/test/run-pass/macro-stmt.rs
src/test/run-pass/macro-use-all-and-none.rs [new file with mode: 0644]
src/test/run-pass/macro-use-all.rs [new file with mode: 0644]
src/test/run-pass/macro-use-both.rs [new file with mode: 0644]
src/test/run-pass/macro-use-one.rs [new file with mode: 0644]
src/test/run-pass/macro-with-attrs1.rs
src/test/run-pass/macro-with-attrs2.rs
src/test/run-pass/macro-with-braces-in-expr-position.rs
src/test/run-pass/match-in-macro.rs
src/test/run-pass/match-var-hygiene.rs
src/test/run-pass/non-built-in-quote.rs
src/test/run-pass/nullable-pointer-iotareduction.rs
src/test/run-pass/nullable-pointer-size.rs
src/test/run-pass/phase-use-ignored.rs [deleted file]
src/test/run-pass/plugin-args-1.rs [new file with mode: 0644]
src/test/run-pass/plugin-args-2.rs [new file with mode: 0644]
src/test/run-pass/plugin-args-3.rs [new file with mode: 0644]
src/test/run-pass/plugin-args-4.rs [new file with mode: 0644]
src/test/run-pass/rust-log-filter.rs
src/test/run-pass/small-enums-with-fields.rs
src/test/run-pass/svh-add-comment.rs
src/test/run-pass/svh-add-doc.rs
src/test/run-pass/svh-add-macro.rs
src/test/run-pass/svh-add-nothing.rs
src/test/run-pass/svh-add-redundant-cfg.rs
src/test/run-pass/svh-add-whitespace.rs
src/test/run-pass/syntax-extension-source-utils.rs
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/two-macro-use.rs [new file with mode: 0644]
src/test/run-pass/typeck-macro-interaction-issue-8852.rs
src/test/run-pass/vec-macro-no-std.rs [new file with mode: 0644]
src/test/run-pass/vec-macro-with-brackets.rs

index 48610b6b526d22899df5a4061453f673fd761cd5..0ce31a335d8ab7d698804a6ed7efd31172d23a67 100644 (file)
 
 extern crate test;
 extern crate getopts;
-#[phase(plugin, link)] extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
 
 extern crate regex;
 
index 58af591740709de8d5174a4ad8e55e2f234d2fea..dc6d281307a7a602e746a599b78f16961f628da9 100644 (file)
@@ -1,14 +1,5 @@
 % The Rust Macros Guide
 
-<div class="unstable-feature">
-<b>Warning:</b> There are currently various problems with invoking macros, how
-they interact with their environment, and how they are used outside of the
-location in which they are defined. Macro definitions are likely to change
-slightly in the future. For this reason, they are hidden behind the
-<code>macro_rules</code> <a href="reference.html#compiler-features">feature
-attribute</a>.
-</div>
-
 # Introduction
 
 Functions are the primary tool that programmers can use to build abstractions.
@@ -46,19 +37,18 @@ lightweight custom syntax extensions, themselves defined using the
 the pattern in the above code:
 
 ~~~~
-# #![feature(macro_rules)]
 # enum T { SpecialA(uint), SpecialB(uint) }
 # fn f() -> uint {
 # let input_1 = T::SpecialA(0);
 # let input_2 = T::SpecialA(0);
-macro_rules! early_return(
+macro_rules! early_return {
     ($inp:expr $sp:path) => ( // invoke it like `(input_5 SpecialE)`
         match $inp {
             $sp(x) => { return x; }
             _ => {}
         }
     );
-);
+}
 // ...
 early_return!(input_1 T::SpecialA);
 // ...
@@ -109,10 +99,10 @@ that could be invoked like: `my_macro!(i->(( 2+2 )))`.
 
 ## Invocation location
 
-A macro invocation may take the place of (and therefore expand to)
-an expression, an item, or a statement.
-The Rust parser will parse the macro invocation as a "placeholder"
-for whichever of those three nonterminals is appropriate for the location.
+A macro invocation may take the place of (and therefore expand to) an
+expression, item, statement, or pattern.  The Rust parser will parse the macro
+invocation as a "placeholder" for whichever syntactic form is appropriate for
+the location.
 
 At expansion time, the output of the macro will be parsed as whichever of the
 three nonterminals it stands in for. This means that a single macro might,
@@ -166,12 +156,11 @@ separator token (a comma-separated list could be written `$(...),*`), and `+`
 instead of `*` to mean "at least one".
 
 ~~~~
-# #![feature(macro_rules)]
 # enum T { SpecialA(uint),SpecialB(uint),SpecialC(uint),SpecialD(uint)}
 # fn f() -> uint {
 # let input_1 = T::SpecialA(0);
 # let input_2 = T::SpecialA(0);
-macro_rules! early_return(
+macro_rules! early_return {
     ($inp:expr, [ $($sp:path)|+ ]) => (
         match $inp {
             $(
@@ -180,7 +169,7 @@ macro_rules! early_return(
             _ => {}
         }
     )
-);
+}
 // ...
 early_return!(input_1, [T::SpecialA|T::SpecialC|T::SpecialD]);
 // ...
@@ -228,7 +217,6 @@ solves the problem.
 Now consider code like the following:
 
 ~~~~
-# #![feature(macro_rules)]
 # enum T1 { Good1(T2, uint), Bad1}
 # struct T2 { body: T3 }
 # enum T3 { Good2(uint), Bad2}
@@ -255,8 +243,7 @@ a match, but with a syntax that suits the problem better. The following macro
 can solve the problem:
 
 ~~~~
-# #![feature(macro_rules)]
-macro_rules! biased_match (
+macro_rules! biased_match {
     // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
     ( ($e:expr) ~ ($p:pat) else $err:stmt ;
       binds $bind_res:ident
@@ -275,7 +262,7 @@ macro_rules! biased_match (
             _ => { $err }
         };
     )
-);
+}
 
 # enum T1 { Good1(T2, uint), Bad1}
 # struct T2 { body: T3 }
@@ -297,13 +284,12 @@ like this, we might prefer to write a single macro invocation. The input
 pattern we want is clear:
 
 ~~~~
-# #![feature(macro_rules)]
 # fn main() {}
-# macro_rules! b(
+# macro_rules! b {
     ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
       binds $( $bind_res:ident ),*
     )
-# => (0));
+# => (0) }
 ~~~~
 
 However, it's not possible to directly expand to nested match statements. But
@@ -320,24 +306,22 @@ process the semicolon-terminated lines, one-by-one. So, we want the following
 input patterns:
 
 ~~~~
-# #![feature(macro_rules)]
-# macro_rules! b(
+# macro_rules! b {
     ( binds $( $bind_res:ident ),* )
-# => (0));
+# => (0) }
 # fn main() {}
 ~~~~
 
 ...and:
 
 ~~~~
-# #![feature(macro_rules)]
 # fn main() {}
-# macro_rules! b(
+# macro_rules! b {
     (    ($e     :expr) ~ ($p     :pat) else $err     :stmt ;
       $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
       binds  $( $bind_res:ident ),*
     )
-# => (0));
+# => (0) }
 ~~~~
 
 The resulting macro looks like this. Note that the separation into
@@ -345,10 +329,9 @@ The resulting macro looks like this. Note that the separation into
 piece of syntax (the `let`) which we only want to transcribe once.
 
 ~~~~
-# #![feature(macro_rules)]
 # fn main() {
 
-macro_rules! biased_match_rec (
+macro_rules! biased_match_rec {
     // Handle the first layer
     (   ($e     :expr) ~ ($p     :pat) else $err     :stmt ;
      $( ($e_rest:expr) ~ ($p_rest:pat) else $err_rest:stmt ; )*
@@ -366,10 +349,10 @@ macro_rules! biased_match_rec (
     );
     // Produce the requested values
     ( binds $( $bind_res:ident ),* ) => ( ($( $bind_res ),*) )
-);
+}
 
 // Wrap the whole thing in a `let`.
-macro_rules! biased_match (
+macro_rules! biased_match {
     // special case: `let (x) = ...` is illegal, so use `let x = ...` instead
     ( $( ($e:expr) ~ ($p:pat) else $err:stmt ; )*
       binds $bind_res:ident
@@ -388,7 +371,7 @@ macro_rules! biased_match (
             binds $( $bind_res ),*
         );
     )
-);
+}
 
 
 # enum T1 { Good1(T2, uint), Bad1}
@@ -434,9 +417,7 @@ As an example, `loop` and `for-loop` labels (discussed in the lifetimes guide)
 will not clash. The following code will print "Hello!" only once:
 
 ~~~
-#![feature(macro_rules)]
-
-macro_rules! loop_x (
+macro_rules! loop_x {
     ($e: expr) => (
         // $e will not interact with this 'x
         'x: loop {
@@ -444,7 +425,7 @@ macro_rules! loop_x (
             $e
         }
     );
-);
+}
 
 fn main() {
     'x: loop {
@@ -467,22 +448,30 @@ lexical-order traversal of a crate's source. So a macro defined at module scope
 is visible to any subsequent code in the same module, which includes the body
 of any subsequent child `mod` items.
 
-If a module has the `macro_escape` attribute, its macros are also visible in
-its parent module after the child's `mod` item. If the parent also has
-`macro_escape` then the macros will be visible in the grandparent after the
-parent's `mod` item, and so forth.
+If a module has the `macro_use` attribute, its macros are also visible in its
+parent module after the child's `mod` item. If the parent also has `macro_use`
+then the macros will be visible in the grandparent after the parent's `mod`
+item, and so forth.
 
-Independent of `macro_escape`, the `macro_export` attribute controls visibility
-between crates.  Any `macro_rules!` definition with the `macro_export`
-attribute will be visible to other crates that have loaded this crate with
-`phase(plugin)`. There is currently no way for the importing crate to control
-which macros are imported.
+The `macro_use` attribute can also appear on `extern crate`.  In this context
+it controls which macros are loaded from the external crate, e.g.
+
+```rust,ignore
+#[macro_use(foo, bar)]
+extern crate baz;
+```
+
+If the attribute is given simply as `#[macro_use]`, all macros are loaded.  If
+there is no `#[macro_use]` attribute then no macros are loaded.  Only macros
+defined with the `#[macro_export]` attribute may be loaded.
+
+To load a crate's macros *without* linking it into the output, use `#[no_link]`
+as well.
 
 An example:
 
 ```rust
-# #![feature(macro_rules)]
-macro_rules! m1 (() => (()));
+macro_rules! m1 { () => (()) }
 
 // visible here: m1
 
@@ -490,22 +479,22 @@ mod foo {
     // visible here: m1
 
     #[macro_export]
-    macro_rules! m2 (() => (()));
+    macro_rules! m2 { () => (()) }
 
     // visible here: m1, m2
 }
 
 // visible here: m1
 
-macro_rules! m3 (() => (()));
+macro_rules! m3 { () => (()) }
 
 // visible here: m1, m3
 
-#[macro_escape]
+#[macro_use]
 mod bar {
     // visible here: m1, m3
 
-    macro_rules! m4 (() => (()));
+    macro_rules! m4 { () => (()) }
 
     // visible here: m1, m3, m4
 }
@@ -514,8 +503,58 @@ mod bar {
 # fn main() { }
 ```
 
-When this library is loaded with `#[phase(plugin)] extern crate`, only `m2`
-will be imported.
+When this library is loaded with `#[use_macros] extern crate`, only `m2` will
+be imported.
+
+The Rust Reference has a [listing of macro-related
+attributes](reference.html#macro--and-plugin-related-attributes).
+
+# The variable `$crate`
+
+A further difficulty occurs when a macro is used in multiple crates.  Say that
+`mylib` defines
+
+```rust
+pub fn increment(x: uint) -> uint {
+    x + 1
+}
+
+#[macro_export]
+macro_rules! inc_a {
+    ($x:expr) => ( ::increment($x) )
+}
+
+#[macro_export]
+macro_rules! inc_b {
+    ($x:expr) => ( ::mylib::increment($x) )
+}
+# fn main() { }
+```
+
+`inc_a` only works within `mylib`, while `inc_b` only works outside the
+library.  Furthermore, `inc_b` will break if the user imports `mylib` under
+another name.
+
+Rust does not (yet) have a hygiene system for crate references, but it does
+provide a simple workaround for this problem.  Within a macro imported from a
+crate named `foo`, the special macro variable `$crate` will expand to `::foo`.
+By contrast, when a macro is defined and then used in the same crate, `$crate`
+will expand to nothing.  This means we can write
+
+```rust
+#[macro_export]
+macro_rules! inc {
+    ($x:expr) => ( $crate::increment($x) )
+}
+# fn main() { }
+```
+
+to define a single macro that works both inside and outside our library.  The
+function name will expand to either `::increment` or `::mylib::increment`.
+
+To keep this system simple and correct, `#[macro_use] extern crate ...` may
+only appear at the root of your crate, not inside `mod`.  This ensures that
+`$crate` is a single identifier.
 
 # A final note
 
index eb3e4ce75c4708b98e2d7907c24c721e5e40d579..025f0cced63a6a6cb6b3dd37f793ecd07ba84a99 100644 (file)
@@ -31,10 +31,14 @@ extend the compiler's behavior with new syntax extensions, lint checks, etc.
 
 A plugin is a dynamic library crate with a designated "registrar" function that
 registers extensions with `rustc`. Other crates can use these extensions by
-loading the plugin crate with `#[phase(plugin)] extern crate`. See the
+loading the plugin crate with `#[plugin] extern crate`. See the
 [`rustc::plugin`](rustc/plugin/index.html) documentation for more about the
 mechanics of defining and loading a plugin.
 
+Arguments passed as `#[plugin=...]` or `#[plugin(...)]` are not interpreted by
+rustc itself.  They are provided to the plugin through the `Registry`'s [`args`
+method](rustc/plugin/registry/struct.Registry.html#method.args).
+
 # Syntax extensions
 
 Plugins can extend Rust's syntax in various ways. One kind of syntax extension
@@ -105,10 +109,9 @@ pub fn plugin_registrar(reg: &mut Registry) {
 Then we can use `rn!()` like any other macro:
 
 ```ignore
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
-extern crate roman_numerals;
+#[plugin] extern crate roman_numerals;
 
 fn main() {
     assert_eq!(rn!(MMXV), 2015);
@@ -217,8 +220,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
 Then code like
 
 ```ignore
-#[phase(plugin)]
-extern crate lint_plugin_test;
+#[plugin] extern crate lint_plugin_test;
 
 fn lintme() { }
 ```
index 635e216831fead8e1c817bd604028d0164c4b79d..0f1f26d3e711c8f2d75d3250fef6178e2d61a243 100644 (file)
@@ -193,12 +193,12 @@ grammar as double-quoted strings. Other tokens have exact rules given.
 | break    | const    | continue | crate    | do      |
 | else     | enum     | extern   | false    | final   |
 | fn       | for      | if       | impl     | in      |
-| let      | loop     | match    | mod      | move    |
-| mut      | offsetof | override | priv     | pub     |
-| pure     | ref      | return   | sizeof   | static  |
-| self     | struct   | super    | true     | trait   |
-| type     | typeof   | unsafe   | unsized  | use     |
-| virtual  | where    | while    | yield    |
+| let      | loop     | macro    | match    | mod     |
+| move     | mut      | offsetof | override | priv    |
+| pub      | pure     | ref      | return   | sizeof  |
+| static   | self     | struct   | super    | true    |
+| trait    | type     | typeof   | unsafe   | unsized |
+| use      | virtual  | where    | while    | yield   |
 
 
 Each of these keywords has special meaning in its grammar, and all of them are
@@ -668,9 +668,11 @@ transcriber : '(' transcriber * ')' | '[' transcriber * ']'
             | non_special_token ;
 ```
 
-User-defined syntax extensions are called "macros", and the `macro_rules`
-syntax extension defines them. Currently, user-defined macros can expand to
-expressions, statements, items, or patterns.
+`macro_rules` allows users to define syntax extension in a declarative way.  We
+call such extensions "macros by example" or simply "macros" â€” to be distinguished
+from the "procedural macros" defined in [compiler plugins][plugin].
+
+Currently, macros can expand to expressions, statements, items, or patterns.
 
 (A `sep_token` is any token other than `*` and `+`. A `non_special_token` is
 any token other than a delimiter or `$`.)
@@ -2002,8 +2004,6 @@ type int8_t = i8;
 
 ### Module-only attributes
 
-- `macro_escape` - macros defined in this module will be visible in the
-  module's parent, after this module has been included.
 - `no_implicit_prelude` - disable injecting `use std::prelude::*` in this
   module.
 - `path` - specifies the file to load the module from. `#[path="foo.rs"] mod
@@ -2066,23 +2066,43 @@ On `struct`s:
   remove any padding between fields (note that this is very fragile and may
   break platforms which require aligned access).
 
+### Macro- and plugin-related attributes
+
+- `macro_use` on a `mod` â€” macros defined in this module will be visible in the
+  module's parent, after this module has been included.
+
+- `macro_use` on an `extern crate` â€” load macros from this crate.  An optional
+  list of names `#[macro_use(foo, bar)]` restricts the import to just those
+  macros named.  The `extern crate` must appear at the crate root, not inside
+  `mod`, which ensures proper function of the [`$crate` macro
+  variable](guide-macros.html#the-variable-$crate).
+
+- `macro_reexport` on an `extern crate` â€” re-export the named macros.
+
+- `macro_export` - export a macro for cross-crate usage.
+
+- `plugin` on an `extern crate` — load this crate as a [compiler
+  plugin][plugin].  The `plugin` feature gate is required.  Any arguments to
+  the attribute, e.g. `#[plugin=...]` or `#[plugin(...)]`, are provided to the
+  plugin.
+
+- `no_link` on an `extern crate` â€” even if we load this crate for macros or
+  compiler plugins, don't link it into the output.
+
+See the [macros guide](guide-macros.html#scoping-and-macro-import/export) for
+more information on macro scope.
+
+
 ### Miscellaneous attributes
 
 - `export_name` - on statics and functions, this determines the name of the
   exported symbol.
 - `link_section` - on statics and functions, this specifies the section of the
   object file that this item's contents will be placed into.
-- `macro_export` - export a macro for cross-crate usage.
 - `no_mangle` - on any item, do not apply the standard name mangling. Set the
   symbol for this item to its identifier.
 - `packed` - on structs or enums, eliminate any padding that would be used to
   align fields.
-- `phase` - on `extern crate` statements, allows specifying which "phase" of
-  compilation the crate should be loaded for. Currently, there are two
-  choices: `link` and `plugin`. `link` is the default. `plugin` will [load the
-  crate at compile-time][plugin] and use any syntax extensions or lints that the crate
-  defines. They can both be specified, `#[phase(link, plugin)]` to use a crate
-  both at runtime and compiletime.
 - `simd` - on certain tuple structs, derive the arithmetic operators, which
   lower to the target's SIMD instructions, if any; the `simd` feature gate
   is necessary to use this attribute.
@@ -2569,15 +2589,6 @@ The currently implemented features of the reference compiler are:
 * `log_syntax` - Allows use of the `log_syntax` macro attribute, which is a
                  nasty hack that will certainly be removed.
 
-* `macro_rules` - The definition of new macros. This does not encompass
-                  macro-invocation, that is always enabled by default, this
-                  only covers the definition of new macros. There are currently
-                  various problems with invoking macros, how they interact with
-                  their environment, and possibly how they are used outside of
-                  location in which they are defined. Macro definitions are
-                  likely to change slightly in the future, so they are
-                  currently hidden behind this feature.
-
 * `non_ascii_idents` - The compiler supports the use of non-ascii identifiers,
                        but the implementation is a little rough around the
                        edges, so this can be seen as an experimental feature
@@ -2588,15 +2599,10 @@ The currently implemented features of the reference compiler are:
                closure as `once` is unlikely to be supported going forward. So
                they are hidden behind this feature until they are to be removed.
 
-* `phase` - Usage of the `#[phase]` attribute allows loading compiler plugins
-            for custom lints or syntax extensions. The implementation is
-            considered unwholesome and in need of overhaul, and it is not clear
-            what they will look like moving forward.
+* `plugin` - Usage of [compiler plugins][plugin] for custom lints or syntax extensions.
+             These depend on compiler internals and are subject to change.
 
-* `plugin_registrar` - Indicates that a crate has [compiler plugins][plugin] that it
-                       wants to load. As with `phase`, the implementation is
-                       in need of an overhaul, and it is not clear that plugins
-                       defined using this will continue to work.
+* `plugin_registrar` - Indicates that a crate provides [compiler plugins][plugin].
 
 * `quote` - Allows use of the `quote_*!` family of macros, which are
             implemented very poorly and will likely change significantly
index aa20fe3c395d9855bdf923f51703ce14ccebe7eb..dce6d3f66879e3cca1d93594a22ad555fda3b650 100644 (file)
@@ -56,7 +56,7 @@ syn match rustMacroRepeatCount ".\?[*+]" contained
 syn match rustMacroVariable "$\w\+"
 
 " Reserved (but not yet used) keywords {{{2
-syn keyword   rustReservedKeyword alignof be do offsetof priv pure sizeof typeof unsized yield abstract final override
+syn keyword   rustReservedKeyword alignof be do offsetof priv pure sizeof typeof unsized yield abstract final override macro
 
 " Built-in types {{{2
 syn keyword   rustType        int uint float char bool u8 u16 u32 u64 f32
index db26ca6ffa5d5407589e26460bcecf403658f466..9194c7a47663d66e343750d8c515e39da09b8c8a 100644 (file)
@@ -8,15 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs, phase, macro_rules)]
+#![feature(globs, plugin)]
 
 extern crate syntax;
 extern crate rustc;
 
-#[phase(link)]
 extern crate regex;
 
-#[phase(link, plugin)]
+#[macro_use]
 extern crate log;
 
 use std::collections::HashMap;
@@ -269,7 +268,7 @@ fn next(r: &mut lexer::StringReader) -> TokenAndSpan {
         assert!(rustc_tok.sp == antlr_tok.sp, "{} and {} have different spans", rustc_tok,
                 antlr_tok);
 
-        macro_rules! matches (
+        macro_rules! matches {
             ( $($x:pat),+ ) => (
                 match rustc_tok.tok {
                     $($x => match antlr_tok.tok {
@@ -285,7 +284,7 @@ macro_rules! matches (
                     ref c => assert!(c == &antlr_tok.tok, "{} is not {}", rustc_tok, antlr_tok)
                 }
             )
-        );
+        }
 
         matches!(
             token::Literal(token::Byte(..), _),
index d040f8ff86390f327c3d589c0c3ac045142bea87..001e02f9c0dd5c29cc91e2f0f25ecd51b4697e86 100644 (file)
 #![feature(lang_items, phase, unsafe_destructor, default_type_params, old_orphan_check)]
 #![feature(associated_types)]
 
+#[cfg(stage0)]
 #[phase(plugin, link)]
 extern crate core;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate core;
+
 extern crate libc;
 
 // Allow testing this library
 
-#[cfg(test)] #[phase(plugin, link)] extern crate std;
-#[cfg(test)] #[phase(plugin, link)] extern crate log;
+#[cfg(all(test, stage0))]
+#[phase(plugin, link)]
+extern crate std;
+
+#[cfg(all(test, not(stage0)))]
+#[macro_use]
+extern crate std;
+
+#[cfg(all(test, stage0))]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(all(test, not(stage0)))]
+#[macro_use]
+extern crate log;
 
 // Heaps provided for low-level allocation strategies
 
index c9b090bfb232373551710a94052cb03c1a1ba66e..5bf5f78af94c272381f14d4581bdb9b1946d9c00 100644 (file)
 #![feature(associated_types)]
 #![no_std]
 
-#[phase(plugin, link)] extern crate core;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate core;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate core;
+
 extern crate unicode;
 extern crate alloc;
 
 #[cfg(test)] extern crate test;
 
-#[cfg(test)] #[phase(plugin, link)] extern crate std;
-#[cfg(test)] #[phase(plugin, link)] extern crate log;
+#[cfg(all(test, stage0))]
+#[phase(plugin, link)]
+extern crate std;
+
+#[cfg(all(test, not(stage0)))]
+#[macro_use]
+extern crate std;
 
+#[cfg(all(test, stage0))]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(all(test, not(stage0)))]
+#[macro_use]
+extern crate log;
 
 pub use binary_heap::BinaryHeap;
 pub use bitv::Bitv;
 pub use vec::Vec;
 pub use vec_map::VecMap;
 
+// Needed for the vec! macro
+pub use alloc::boxed;
+
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 mod macros;
 
 pub mod binary_heap;
index ce4b1e467739e05498036d7b5c070e03a729dadf..0c5929e8661d6d22870fbab4f215118834675009 100644 (file)
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
 /// Creates a `std::vec::Vec` containing the arguments.
+// NOTE: remove after the next snapshot
+#[cfg(stage0)]
 macro_rules! vec {
     ($($e:expr),*) => ({
         // leading _ to allow empty construction without a warning.
@@ -21,3 +21,13 @@ macro_rules! vec {
     ($($e:expr),+,) => (vec!($($e),+))
 }
 
+/// Creates a `Vec` containing the arguments.
+#[cfg(not(stage0))]
+#[macro_export]
+macro_rules! vec {
+    ($($x:expr),*) => ({
+        let xs: $crate::boxed::Box<[_]> = box [$($x),*];
+        $crate::slice::SliceExt::into_vec(xs)
+    });
+    ($($x:expr,)*) => (vec![$($x),*])
+}
index f286b99e04536f7d6bfb7b4fc145500b619e968d..1cb9e9009db62bd8c30ee33e496ed73d585cee57 100644 (file)
@@ -2598,13 +2598,13 @@ fn test_reverse_part() {
 
     #[test]
     fn test_show() {
-        macro_rules! test_show_vec(
+        macro_rules! test_show_vec {
             ($x:expr, $x_str:expr) => ({
                 let (x, x_str) = ($x, $x_str);
                 assert_eq!(format!("{}", x), x_str);
                 assert_eq!(format!("{}", x.as_slice()), x_str);
             })
-        );
+        }
         let empty: Vec<int> = vec![];
         test_show_vec!(empty, "[]");
         test_show_vec!(vec![1i], "[1]");
@@ -2624,12 +2624,12 @@ macro_rules! test_show_vec(
 
     #[test]
     fn test_vec_default() {
-        macro_rules! t (
+        macro_rules! t {
             ($ty:ty) => {{
                 let v: $ty = Default::default();
                 assert!(v.is_empty());
             }}
-        );
+        }
 
         t!(&[int]);
         t!(Vec<int>);
index f994348ffe7ab0d973612e8aeb29b95cadbe8a2b..c0482702ccdb66c1a6ee149ebaa0811d7a66808b 100644 (file)
@@ -1846,7 +1846,9 @@ fn test_is_utf8() {
     #[test]
     fn test_is_utf16() {
         use unicode::str::is_utf16;
-        macro_rules! pos ( ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } });
+        macro_rules! pos {
+            ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } }
+        }
 
         // non-surrogates
         pos!(&[0x0000],
@@ -1866,7 +1868,9 @@ fn test_is_utf16() {
              &[0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
 
         // negative tests
-        macro_rules! neg ( ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } });
+        macro_rules! neg {
+            ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } }
+        }
 
         neg!(
             // surrogate + regular unit
index 6d7ebeff094882a3c5bbec65f8d8c2406d4be423..0bf311e4d3f6e5674bc1eb9fd32f097087bea6e4 100644 (file)
@@ -182,7 +182,7 @@ fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 {
             let byte = unsafe_get(v, i);
             i += 1;
 
-            macro_rules! error(() => ({
+            macro_rules! error { () => ({
                 unsafe {
                     if subseqidx != i_ {
                         res.as_mut_vec().push_all(v[subseqidx..i_]);
@@ -190,7 +190,7 @@ macro_rules! error(() => ({
                     subseqidx = i;
                     res.as_mut_vec().push_all(REPLACEMENT);
                 }
-            }));
+            })}
 
             if byte < 128u8 {
                 // subseqidx handles this
index 7d92b707f98c37b7d9deefe14f9526a75e1e961e..951f5c29f00e8c923c5520e0bb9c0c341360f7b7 100644 (file)
 use option::Option;
 use option::Option::{Some, None};
 use ops::{Deref, FnOnce};
-use result::Result::{Ok, Err};
+use result::Result::Ok;
 use result;
 use slice::SliceExt;
 use slice;
 use str::{self, StrExt, Utf8Error};
 
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::Err;
+
 pub use self::num::radix;
 pub use self::num::Radix;
 pub use self::num::RadixFmt;
index d646245510d505394c1553dff7fac7bef96f4e11..aff0065c52744d8d8430b8d7b9c69ef9125213cd 100644 (file)
 #![feature(default_type_params, unboxed_closures, associated_types)]
 #![deny(missing_docs)]
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 mod macros;
 
-#[path = "num/float_macros.rs"] mod float_macros;
-#[path = "num/int_macros.rs"]   mod int_macros;
-#[path = "num/uint_macros.rs"]  mod uint_macros;
+#[path = "num/float_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod float_macros;
+
+#[path = "num/int_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod int_macros;
+
+#[path = "num/uint_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod uint_macros;
 
 #[path = "num/int.rs"]  pub mod int;
 #[path = "num/i8.rs"]   pub mod i8;
 #[doc(hidden)]
 mod core {
     pub use panicking;
+    pub use fmt;
 }
 
 #[doc(hidden)]
index e8fbd9d930f3388c8c4b3622cc2bad7affc865ca..a579f9db4161c3a8f04b1742a1f53d1602a7e96a 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
 /// Entry point of task panic, for details, see std::macros
 #[macro_export]
 macro_rules! panic {
@@ -30,7 +28,26 @@ macro_rules! panic {
     });
 }
 
-/// Runtime assertion, for details see std::macros
+/// Ensure that a boolean expression is `true` at runtime.
+///
+/// This will invoke the `panic!` macro if the provided expression cannot be
+/// evaluated to `true` at runtime.
+///
+/// # Example
+///
+/// ```
+/// // the panic message for these assertions is the stringified value of the
+/// // expression given.
+/// assert!(true);
+/// # fn some_computation() -> bool { true }
+/// assert!(some_computation());
+///
+/// // assert with a custom message
+/// # let x = true;
+/// assert!(x, "x wasn't true!");
+/// # let a = 3i; let b = 27i;
+/// assert!(a + b == 30, "a = {}, b = {}", a, b);
+/// ```
 #[macro_export]
 macro_rules! assert {
     ($cond:expr) => (
@@ -38,61 +55,197 @@ macro_rules! assert {
             panic!(concat!("assertion failed: ", stringify!($cond)))
         }
     );
-    ($cond:expr, $($arg:tt)*) => (
+    ($cond:expr, $($arg:expr),+) => (
         if !$cond {
-            panic!($($arg)*)
+            panic!($($arg),+)
         }
     );
 }
 
-/// Runtime assertion for equality, for details see std::macros
+/// Asserts that two expressions are equal to each other, testing equality in
+/// both directions.
+///
+/// On panic, this macro will print the values of the expressions.
+///
+/// # Example
+///
+/// ```
+/// let a = 3i;
+/// let b = 1i + 2i;
+/// assert_eq!(a, b);
+/// ```
 #[macro_export]
 macro_rules! assert_eq {
-    ($cond1:expr, $cond2:expr) => ({
-        let c1 = $cond1;
-        let c2 = $cond2;
-        if c1 != c2 || c2 != c1 {
-            panic!("expressions not equal, left: {}, right: {}", c1, c2);
+    ($left:expr , $right:expr) => ({
+        match (&($left), &($right)) {
+            (left_val, right_val) => {
+                // check both directions of equality....
+                if !((*left_val == *right_val) &&
+                     (*right_val == *left_val)) {
+                    panic!("assertion failed: `(left == right) && (right == left)` \
+                           (left: `{}`, right: `{}`)", *left_val, *right_val)
+                }
+            }
         }
     })
 }
 
-/// Runtime assertion for equality, only without `--cfg ndebug`
+/// Ensure that a boolean expression is `true` at runtime.
+///
+/// This will invoke the `panic!` macro if the provided expression cannot be
+/// evaluated to `true` at runtime.
+///
+/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
+/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
+/// checks that are too expensive to be present in a release build but may be
+/// helpful during development.
+///
+/// # Example
+///
+/// ```
+/// // the panic message for these assertions is the stringified value of the
+/// // expression given.
+/// debug_assert!(true);
+/// # fn some_expensive_computation() -> bool { true }
+/// debug_assert!(some_expensive_computation());
+///
+/// // assert with a custom message
+/// # let x = true;
+/// debug_assert!(x, "x wasn't true!");
+/// # let a = 3i; let b = 27i;
+/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
+/// ```
+#[macro_export]
+macro_rules! debug_assert {
+    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+}
+
+/// Asserts that two expressions are equal to each other, testing equality in
+/// both directions.
+///
+/// On panic, this macro will print the values of the expressions.
+///
+/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
+/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
+/// useful for checks that are too expensive to be present in a release build
+/// but may be helpful during development.
+///
+/// # Example
+///
+/// ```
+/// let a = 3i;
+/// let b = 1i + 2i;
+/// debug_assert_eq!(a, b);
+/// ```
 #[macro_export]
 macro_rules! debug_assert_eq {
-    ($($a:tt)*) => ({
-        if cfg!(not(ndebug)) {
-            assert_eq!($($a)*);
-        }
-    })
+    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
 }
 
-/// Runtime assertion, disableable at compile time with `--cfg ndebug`
+#[cfg(stage0)]
 #[macro_export]
-macro_rules! debug_assert {
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+macro_rules! try {
+    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
 }
 
 /// Short circuiting evaluation on Err
+///
+/// `libstd` contains a more general `try!` macro that uses `FromError`.
+#[cfg(not(stage0))]
 #[macro_export]
 macro_rules! try {
-    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+    ($e:expr) => ({
+        use $crate::result::Result::{Ok, Err};
+
+        match $e {
+            Ok(e) => e,
+            Err(e) => return Err(e),
+        }
+    })
 }
 
-/// Writing a formatted string into a writer
+/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
+/// See `std::fmt` for more information.
+///
+/// # Example
+///
+/// ```
+/// # #![allow(unused_must_use)]
+///
+/// let mut w = Vec::new();
+/// write!(&mut w, "test");
+/// write!(&mut w, "formatted {}", "arguments");
+/// ```
 #[macro_export]
 macro_rules! write {
     ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
 }
 
-/// Writing a formatted string plus a newline into a writer
+/// Equivalent to the `write!` macro, except that a newline is appended after
+/// the message is written.
 #[macro_export]
+#[stable]
 macro_rules! writeln {
     ($dst:expr, $fmt:expr $($arg:tt)*) => (
         write!($dst, concat!($fmt, "\n") $($arg)*)
     )
 }
 
+/// A utility macro for indicating unreachable code.
+///
+/// This is useful any time that the compiler can't determine that some code is unreachable. For
+/// example:
+///
+/// * Match arms with guard conditions.
+/// * Loops that dynamically terminate.
+/// * Iterators that dynamically terminate.
+///
+/// # Panics
+///
+/// This will always panic.
+///
+/// # Examples
+///
+/// Match arms:
+///
+/// ```rust
+/// fn foo(x: Option<int>) {
+///     match x {
+///         Some(n) if n >= 0 => println!("Some(Non-negative)"),
+///         Some(n) if n <  0 => println!("Some(Negative)"),
+///         Some(_)           => unreachable!(), // compile error if commented out
+///         None              => println!("None")
+///     }
+/// }
+/// ```
+///
+/// Iterators:
+///
+/// ```rust
+/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
+///     for i in std::iter::count(0_u32, 1) {
+///         if 3*i < i { panic!("u32 overflow"); }
+///         if x < 3*i { return i-1; }
+///     }
+///     unreachable!();
+/// }
+/// ```
 #[macro_export]
-macro_rules! unreachable { () => (panic!("unreachable code")) }
+macro_rules! unreachable {
+    () => ({
+        panic!("internal error: entered unreachable code")
+    });
+    ($msg:expr) => ({
+        unreachable!("{}", $msg)
+    });
+    ($fmt:expr, $($arg:tt)*) => ({
+        panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
+    });
+}
 
+/// A standardised placeholder for marking unfinished code. It panics with the
+/// message `"not yet implemented"` when executed.
+#[macro_export]
+macro_rules! unimplemented {
+    () => (panic!("not yet implemented"))
+}
index 97de61d7e272eebb0becea999c7f39770bda8a96..20300d29fa0c5f1e66e5d255eb79bc5b1c11ed17 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
 #![doc(hidden)]
 
 macro_rules! assert_approx_eq {
index 522eab9180c86bce7bc2c85d575ccb143c922630..61cd8cbf7c10153da90d5f0da64168ae845e5e1a 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
 #![doc(hidden)]
 
 macro_rules! int_module { ($T:ty, $bits:expr) => (
index 82eca0d46598204a08f0aa63ce0f447207f76f10..535765840a0fcacc345b9065311456d9e644bdf7 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
 #![doc(hidden)]
 
 macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
index 7293ed6455b084aa74cd5932a0b494b75cc99ec8..8e9bf5487e3ed1faa974a1a3e04a6d8944af98a3 100644 (file)
 //!
 //! ```
 //! # #![feature(macro_rules)]
-//! macro_rules! try(
+//! macro_rules! try {
 //!     ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
-//! );
+//! }
 //! # fn main() { }
 //! ```
 //!
index d9749899b22103a86751dd47dacf7341a05b8262..a39787b8207b5161c2fcbdb54c899d0829a93e11 100644 (file)
@@ -964,17 +964,18 @@ fn run_utf8_validation_iterator(iter: &mut slice::Iter<u8>)
         let old = *iter;
 
         // restore the iterator we had at the start of this codepoint.
-        macro_rules! err (() => { {
+        macro_rules! err { () => {{
             *iter = old;
             return Err(Utf8Error::InvalidByte(whole.len() - iter.as_slice().len()))
-        } });
-        macro_rules! next ( () => {
+        }}}
+
+        macro_rules! next { () => {
             match iter.next() {
                 Some(a) => *a,
                 // we needed data, but there was none: error!
                 None => return Err(Utf8Error::TooShort),
             }
-        });
+        }}
 
         let first = match iter.next() {
             Some(&b) => b,
index b6fc6457fce4d8f3454c8ef0e90465f5802aa352..50ae59e70dc930ec32e21d96a444345b4b8f1bc9 100644 (file)
@@ -7,7 +7,7 @@
 // <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.
-#![feature(globs, unsafe_destructor, macro_rules, slicing_syntax, default_type_params)]
+#![feature(globs, unsafe_destructor, slicing_syntax, default_type_params)]
 #![feature(unboxed_closures)]
 
 extern crate core;
index 8885d3a52082cd3571fb59e89ea682cbbe01c01a..b98432e26b215c739066af43918ea4f20ee76f8e 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
-macro_rules! int_module (($T:ty, $T_i:ident) => (
+macro_rules! int_module { ($T:ty, $T_i:ident) => (
 #[cfg(test)]
 mod tests {
     use core::$T_i::*;
@@ -205,4 +203,4 @@ fn test_from_str_radix() {
     }
 }
 
-));
+)}
index 651e8640e912a399ac3f7e6a343af4a81e1b7357..f86c85f821638f98813ab459ea8dab0293e00331 100644 (file)
 use core::ops::{Add, Sub, Mul, Div, Rem};
 use core::kinds::Copy;
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 mod int_macros;
+
 mod i8;
 mod i16;
 mod i32;
 mod i64;
 mod int;
+
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 mod uint_macros;
+
 mod u8;
 mod u16;
 mod u32;
index 2311c19d5573ae0200d571f7c922ff15a237f2a8..04d8fb15cf5aa41715d3043adf44c0fc95805c23 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
-macro_rules! uint_module (($T:ty, $T_i:ident) => (
+macro_rules! uint_module { ($T:ty, $T_i:ident) => (
 #[cfg(test)]
 mod tests {
     use core::$T_i::*;
@@ -125,4 +123,5 @@ fn test_unsigned_checked_div() {
         assert!(5u.checked_div(0) == None);
     }
 }
-));
+
+)}
index a0c9da3ae6d497a3ddeb818a189c0b2a597f956c..6ac311fe4b646ae2f5d9a8ae5642a8b5f0fd6e11 100644 (file)
@@ -21,9 +21,9 @@
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/")]
-#![feature(phase, unboxed_closures, associated_types)]
+#![feature(unboxed_closures, associated_types)]
 
-#[cfg(test)] #[phase(plugin, link)] extern crate log;
+#[cfg(test)] #[macro_use] extern crate log;
 
 extern crate libc;
 
index a4d89bf301ec61127e531e7d362cd07163d76a8f..917c6e99992f24c2aa084a23d03352b695516cb4 100644 (file)
@@ -23,7 +23,7 @@
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
 
-#![feature(macro_rules, globs, slicing_syntax)]
+#![feature(globs, slicing_syntax)]
 #![feature(associated_types)]
 
 pub use self::Piece::*;
index 2063654077f15c0998e106a6b49fee30899408ed..18077795e245f16dda711c3bc2c62a0373e86d83 100644 (file)
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/nightly/",
        html_playground_url = "http://play.rust-lang.org/")]
-#![feature(globs, phase, slicing_syntax)]
+#![feature(globs, slicing_syntax)]
 #![feature(unboxed_closures)]
 #![deny(missing_docs)]
 
-#[cfg(test)] #[phase(plugin, link)] extern crate log;
+#[cfg(test)] #[macro_use] extern crate log;
 
 use self::Name::*;
 use self::HasArg::*;
index 0508402ff19d8cd96f79b95bb5de8548d43516a2..df85e89efd17c5a805f46094b1766e0ba76be7e7 100644 (file)
@@ -13,8 +13,7 @@
 //! # Examples
 //!
 //! ```
-//! #![feature(phase)]
-//! #[phase(plugin, link)] extern crate log;
+//! #[macro_use] extern crate log;
 //!
 //! fn main() {
 //!     debug!("this is a debug {}", "message");
 
 use directive::LOG_LEVEL_NAMES;
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 pub mod macros;
+
 mod directive;
 
 /// Maximum logging level of a module that can be specified. Common logging
index f41a4a8b901a8f329e11fe9802572ccb4b88788b..5c7085b7b6c5f8909a451fcaf892ba473d66b6a7 100644 (file)
@@ -10,8 +10,6 @@
 
 //! Logging macros
 
-#![macro_escape]
-
 /// The standard logging macro
 ///
 /// This macro will generically log over a provided level (of type u32) with a
@@ -21,8 +19,7 @@
 /// # Example
 ///
 /// ```
-/// #![feature(phase)]
-/// #[phase(plugin, link)] extern crate log;
+/// #[macro_use] extern crate log;
 ///
 /// fn main() {
 ///     log!(log::WARN, "this is a warning {}", "message");
@@ -70,8 +67,7 @@ macro_rules! log {
 /// # Example
 ///
 /// ```
-/// #![feature(phase)]
-/// #[phase(plugin, link)] extern crate log;
+/// #[macro_use] extern crate log;
 ///
 /// fn main() {
 ///     let error = 3u;
@@ -96,8 +92,7 @@ macro_rules! error {
 /// # Example
 ///
 /// ```
-/// #![feature(phase)]
-/// #[phase(plugin, link)] extern crate log;
+/// #[macro_use] extern crate log;
 ///
 /// fn main() {
 ///     let code = 3u;
@@ -121,8 +116,7 @@ macro_rules! warn {
 /// # Example
 ///
 /// ```
-/// #![feature(phase)]
-/// #[phase(plugin, link)] extern crate log;
+/// #[macro_use] extern crate log;
 ///
 /// fn main() {
 ///     let ret = 3;
@@ -148,8 +142,7 @@ macro_rules! info {
 /// # Example
 ///
 /// ```
-/// #![feature(phase)]
-/// #[phase(plugin, link)] extern crate log;
+/// #[macro_use] extern crate log;
 ///
 /// fn main() {
 ///     debug!("x = {x}, y = {y}", x=10, y=20);
@@ -172,8 +165,7 @@ macro_rules! debug {
 /// # Example
 ///
 /// ```
-/// #![feature(phase)]
-/// #[phase(plugin, link)] extern crate log;
+/// #[macro_use] extern crate log;
 ///
 /// struct Point { x: int, y: int }
 /// fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } }
index e684fcf40f7b37d19dac4896bbeebb36dced8307..2fdba8a6c4f960358a1c064d4d6ec7561cdb06ef 100644 (file)
@@ -297,7 +297,7 @@ fn test_weighted_choice() {
         // it doesn't do weird things to the RNG (so 0 maps to 0, 1 to
         // 1, internally; modulo a modulo operation).
 
-        macro_rules! t (
+        macro_rules! t {
             ($items:expr, $expected:expr) => {{
                 let mut items = $items;
                 let wc = WeightedChoice::new(items.as_mut_slice());
@@ -309,7 +309,7 @@ macro_rules! t (
                     assert_eq!(wc.ind_sample(&mut rng), val)
                 }
             }}
-        );
+        }
 
         t!(vec!(Weighted { weight: 1, item: 10i}), [10]);
 
index 558fa2012567591e312d39a657e2f9480bc0337c..1038009522d67313af1e85c46f03d166a2f9222e 100644 (file)
@@ -182,7 +182,7 @@ fn test_range_bad_limits_flipped() {
     #[test]
     fn test_integers() {
         let mut rng = ::test::rng();
-        macro_rules! t (
+        macro_rules! t {
             ($($ty:ty),*) => {{
                 $(
                    let v: &[($ty, $ty)] = &[(0, 10),
@@ -199,7 +199,7 @@ macro_rules! t (
                     }
                  )*
             }}
-        );
+        }
         t!(i8, i16, i32, i64, int,
            u8, u16, u32, u64, uint)
     }
@@ -207,7 +207,7 @@ macro_rules! t (
     #[test]
     fn test_floats() {
         let mut rng = ::test::rng();
-        macro_rules! t (
+        macro_rules! t {
             ($($ty:ty),*) => {{
                 $(
                    let v: &[($ty, $ty)] = &[(0.0, 100.0),
@@ -225,7 +225,7 @@ macro_rules! t (
                     }
                  )*
             }}
-        );
+        }
 
         t!(f32, f64)
     }
index 03b56963ba944e4229096bba33bdee12f39868b9..84328360ce32431e7b40f0ca582d2268ada3feee 100644 (file)
@@ -69,7 +69,7 @@ fn init(&mut self, use_rsl: bool) {
         let mut g = a;
         let mut h = a;
 
-        macro_rules! mix(
+        macro_rules! mix {
             () => {{
                 a^=b<<11; d+=a; b+=c;
                 b^=c>>2;  e+=b; c+=d;
@@ -80,14 +80,14 @@ macro_rules! mix(
                 g^=h<<8;  b+=g; h+=a;
                 h^=a>>9;  c+=h; a+=b;
             }}
-        );
+        }
 
         for _ in range(0u, 4) {
             mix!();
         }
 
         if use_rsl {
-            macro_rules! memloop (
+            macro_rules! memloop {
                 ($arr:expr) => {{
                     for i in range_step(0, RAND_SIZE as uint, 8) {
                         a+=$arr[i  ]; b+=$arr[i+1];
@@ -101,7 +101,7 @@ macro_rules! memloop (
                         self.mem[i+6]=g; self.mem[i+7]=h;
                     }
                 }}
-            );
+            }
 
             memloop!(self.rsl);
             memloop!(self.mem);
@@ -129,41 +129,42 @@ fn isaac(&mut self) {
 
         static MIDPOINT: uint = (RAND_SIZE / 2) as uint;
 
-        macro_rules! ind (($x:expr) => {
-            self.mem[(($x >> 2) as uint & ((RAND_SIZE - 1) as uint))]
-        });
+        macro_rules! ind {
+            ($x:expr) => ( self.mem[(($x >> 2) as uint & ((RAND_SIZE - 1) as uint))] )
+        }
 
         let r = [(0, MIDPOINT), (MIDPOINT, 0)];
         for &(mr_offset, m2_offset) in r.iter() {
 
-            macro_rules! rngstepp(
+            macro_rules! rngstepp {
                 ($j:expr, $shift:expr) => {{
-                        let base = $j;
-                        let mix = a << $shift as uint;
+                    let base = $j;
+                    let mix = a << $shift as uint;
 
-                        let x = self.mem[base  + mr_offset];
-                        a = (a ^ mix) + self.mem[base + m2_offset];
-                        let y = ind!(x) + a + b;
-                        self.mem[base + mr_offset] = y;
+                    let x = self.mem[base  + mr_offset];
+                    a = (a ^ mix) + self.mem[base + m2_offset];
+                    let y = ind!(x) + a + b;
+                    self.mem[base + mr_offset] = y;
 
-                        b = ind!(y >> RAND_SIZE_LEN as uint) + x;
-                        self.rsl[base + mr_offset] = b;
-                    }}
-                );
-            macro_rules! rngstepn(
+                    b = ind!(y >> RAND_SIZE_LEN as uint) + x;
+                    self.rsl[base + mr_offset] = b;
+                }}
+            }
+
+            macro_rules! rngstepn {
                 ($j:expr, $shift:expr) => {{
-                        let base = $j;
-                        let mix = a >> $shift as uint;
+                    let base = $j;
+                    let mix = a >> $shift as uint;
 
-                        let x = self.mem[base  + mr_offset];
-                        a = (a ^ mix) + self.mem[base + m2_offset];
-                        let y = ind!(x) + a + b;
-                        self.mem[base + mr_offset] = y;
+                    let x = self.mem[base  + mr_offset];
+                    a = (a ^ mix) + self.mem[base + m2_offset];
+                    let y = ind!(x) + a + b;
+                    self.mem[base + mr_offset] = y;
 
-                        b = ind!(y >> RAND_SIZE_LEN as uint) + x;
-                        self.rsl[base + mr_offset] = b;
-                    }}
-                );
+                    b = ind!(y >> RAND_SIZE_LEN as uint) + x;
+                    self.rsl[base + mr_offset] = b;
+                }}
+            }
 
             for i in range_step(0u, MIDPOINT, 4) {
                 rngstepp!(i + 0, 13);
@@ -301,15 +302,15 @@ pub fn new_unseeded() -> Isaac64Rng {
     /// of `rsl` as a seed, otherwise construct one algorithmically (not
     /// randomly).
     fn init(&mut self, use_rsl: bool) {
-        macro_rules! init (
+        macro_rules! init {
             ($var:ident) => (
                 let mut $var = 0x9e3779b97f4a7c13;
             )
-        );
+        }
         init!(a); init!(b); init!(c); init!(d);
         init!(e); init!(f); init!(g); init!(h);
 
-        macro_rules! mix(
+        macro_rules! mix {
             () => {{
                 a-=e; f^=h>>9;  h+=a;
                 b-=f; g^=a<<9;  a+=b;
@@ -320,14 +321,14 @@ macro_rules! mix(
                 g-=c; d^=f>>17; f+=g;
                 h-=d; e^=g<<14; g+=h;
             }}
-        );
+        }
 
         for _ in range(0u, 4) {
             mix!();
         }
 
         if use_rsl {
-            macro_rules! memloop (
+            macro_rules! memloop {
                 ($arr:expr) => {{
                     for i in range(0, RAND_SIZE_64 / 8).map(|i| i * 8) {
                         a+=$arr[i  ]; b+=$arr[i+1];
@@ -341,7 +342,7 @@ macro_rules! memloop (
                         self.mem[i+6]=g; self.mem[i+7]=h;
                     }
                 }}
-            );
+            }
 
             memloop!(self.rsl);
             memloop!(self.mem);
@@ -366,49 +367,51 @@ fn isaac64(&mut self) {
         let mut b = self.b + self.c;
         const MIDPOINT: uint =  RAND_SIZE_64 / 2;
         const MP_VEC: [(uint, uint); 2] = [(0,MIDPOINT), (MIDPOINT, 0)];
-        macro_rules! ind (
+        macro_rules! ind {
             ($x:expr) => {
                 *self.mem.get_unchecked(($x as uint >> 3) & (RAND_SIZE_64 - 1))
             }
-        );
+        }
 
         for &(mr_offset, m2_offset) in MP_VEC.iter() {
             for base in range(0, MIDPOINT / 4).map(|i| i * 4) {
 
-                macro_rules! rngstepp(
+                macro_rules! rngstepp {
                     ($j:expr, $shift:expr) => {{
-                            let base = base + $j;
-                            let mix = a ^ (a << $shift as uint);
-                            let mix = if $j == 0 {!mix} else {mix};
-
-                            unsafe {
-                                let x = *self.mem.get_unchecked(base + mr_offset);
-                                a = mix + *self.mem.get_unchecked(base + m2_offset);
-                                let y = ind!(x) + a + b;
-                                *self.mem.get_unchecked_mut(base + mr_offset) = y;
-
-                                b = ind!(y >> RAND_SIZE_64_LEN) + x;
-                                *self.rsl.get_unchecked_mut(base + mr_offset) = b;
-                            }
-                        }}
-                    );
-                macro_rules! rngstepn(
+                        let base = base + $j;
+                        let mix = a ^ (a << $shift as uint);
+                        let mix = if $j == 0 {!mix} else {mix};
+
+                        unsafe {
+                            let x = *self.mem.get_unchecked(base + mr_offset);
+                            a = mix + *self.mem.get_unchecked(base + m2_offset);
+                            let y = ind!(x) + a + b;
+                            *self.mem.get_unchecked_mut(base + mr_offset) = y;
+
+                            b = ind!(y >> RAND_SIZE_64_LEN) + x;
+                            *self.rsl.get_unchecked_mut(base + mr_offset) = b;
+                        }
+                    }}
+                }
+
+                macro_rules! rngstepn {
                     ($j:expr, $shift:expr) => {{
-                            let base = base + $j;
-                            let mix = a ^ (a >> $shift as uint);
-                            let mix = if $j == 0 {!mix} else {mix};
-
-                            unsafe {
-                                let x = *self.mem.get_unchecked(base + mr_offset);
-                                a = mix + *self.mem.get_unchecked(base + m2_offset);
-                                let y = ind!(x) + a + b;
-                                *self.mem.get_unchecked_mut(base + mr_offset) = y;
-
-                                b = ind!(y >> RAND_SIZE_64_LEN) + x;
-                                *self.rsl.get_unchecked_mut(base + mr_offset) = b;
-                            }
-                        }}
-                    );
+                        let base = base + $j;
+                        let mix = a ^ (a >> $shift as uint);
+                        let mix = if $j == 0 {!mix} else {mix};
+
+                        unsafe {
+                            let x = *self.mem.get_unchecked(base + mr_offset);
+                            a = mix + *self.mem.get_unchecked(base + m2_offset);
+                            let y = ind!(x) + a + b;
+                            *self.mem.get_unchecked_mut(base + mr_offset) = y;
+
+                            b = ind!(y >> RAND_SIZE_64_LEN) + x;
+                            *self.rsl.get_unchecked_mut(base + mr_offset) = b;
+                        }
+                    }}
+                }
+
                 rngstepp!(0u, 21);
                 rngstepn!(1u, 5);
                 rngstepp!(2u, 12);
index f538e0ade05f5f5e1d32fe442c82a2389dbf7ae9..99dd505a9ef3910ee3342d16f2d03015e0929837 100644 (file)
 #![no_std]
 #![experimental]
 
+#[cfg(stage0)]
 #[phase(plugin, link)]
 extern crate core;
 
-#[cfg(test)] #[phase(plugin, link)] extern crate std;
-#[cfg(test)] #[phase(plugin, link)] extern crate log;
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate core;
+
+#[cfg(all(test, stage0))]
+#[phase(plugin, link)]
+extern crate std;
+
+#[cfg(all(test, not(stage0)))]
+#[macro_use]
+extern crate std;
+
+#[cfg(all(test, stage0))]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(all(test, not(stage0)))]
+#[macro_use]
+extern crate log;
 
 use core::prelude::*;
 
index 3acedac111d606b97aff651a95af57821f7d6257..e57542a6d14de1c1e2e08f91d51fe59ed594dc0f 100644 (file)
 
 extern crate serialize;
 
-#[phase(plugin, link)] extern crate log;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
 #[cfg(test)] extern crate test;
 
 pub use self::EbmlEncoderTag::*;
index b3807d313145d0e13a7e78e96ff04e2a1a102c00..0084be49b561904534e693d4b69e736ab96f5eff 100644 (file)
@@ -24,7 +24,7 @@
        html_playground_url = "http://play.rust-lang.org/")]
 
 #![allow(unknown_features)]
-#![feature(macro_rules, phase, slicing_syntax, globs)]
+#![feature(macro_rules, slicing_syntax, globs)]
 #![feature(unboxed_closures)]
 #![feature(associated_types)]
 #![deny(missing_docs)]
index 122171e469108639178925a2e70b62b716bb075c..3ed712b15dfdcdb4eba468811aaff5a1634d3a42 100644 (file)
 extern crate serialize;
 extern crate rbml;
 extern crate collections;
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
 
 extern crate "serialize" as rustc_serialize; // used by deriving
 
index 521e5e305bc77529df3d4b475e03cc93295aa485..5c0fd8944368f60da86abc2a3a85b2860e3de174 100644 (file)
@@ -167,21 +167,27 @@ fn register_renamed(&mut self, old_name: &str, new_name: &str) {
     }
 
     pub fn register_builtin(&mut self, sess: Option<&Session>) {
-        macro_rules! add_builtin ( ( $sess:ident, $($name:ident),*, ) => (
-            {$(
-                self.register_pass($sess, false, box builtin::$name as LintPassObject);
-            )*}
-        ));
-
-        macro_rules! add_builtin_with_new ( ( $sess:ident, $($name:ident),*, ) => (
-            {$(
-                self.register_pass($sess, false, box builtin::$name::new() as LintPassObject);
-            )*}
-        ));
-
-        macro_rules! add_lint_group ( ( $sess:ident, $name:expr, $($lint:ident),* ) => (
-            self.register_group($sess, false, $name, vec![$(LintId::of(builtin::$lint)),*]);
-        ));
+        macro_rules! add_builtin {
+            ($sess:ident, $($name:ident),*,) => (
+                {$(
+                    self.register_pass($sess, false, box builtin::$name as LintPassObject);
+                )*}
+            )
+        }
+
+        macro_rules! add_builtin_with_new {
+            ($sess:ident, $($name:ident),*,) => (
+                {$(
+                    self.register_pass($sess, false, box builtin::$name::new() as LintPassObject);
+                )*}
+            )
+        }
+
+        macro_rules! add_lint_group {
+            ($sess:ident, $name:expr, $($lint:ident),*) => (
+                self.register_group($sess, false, $name, vec![$(LintId::of(builtin::$lint)),*]);
+            )
+        }
 
         add_builtin!(sess,
                      HardwiredLints,
index 461a67ba93793cbe7d62124c67480afbe15316cd..e9778fa05ff1787f419d717d979591d8816a69ef 100644 (file)
@@ -28,8 +28,6 @@
 //! example) requires more effort. See `emit_lint` and `GatherNodeLevels`
 //! in `context.rs`.
 
-#![macro_escape]
-
 pub use self::Level::*;
 pub use self::LintSource::*;
 
index ca7c65c8e2bc220223d2845e4832206e7fed0b9b..de9a09ffe44c1ba33dddee1c55b41199e02dbe20 100644 (file)
@@ -206,8 +206,8 @@ pub fn from_uint(value : uint) -> Option<astencode_tag> {
 pub const tag_native_libraries_kind: uint = 0x8a;
 
 pub const tag_plugin_registrar_fn: uint = 0x8b;
-pub const tag_exported_macros: uint = 0x8c;
-pub const tag_macro_def: uint = 0x8d;
+
+// GAP 0x8c, 0x8d
 
 pub const tag_method_argument_names: uint = 0x8e;
 pub const tag_method_argument_name: uint = 0x8f;
@@ -261,3 +261,7 @@ pub struct LinkMeta {
 pub const tag_associated_type_name: uint = 0xb3;
 
 pub const tag_polarity: uint = 0xb4;
+
+pub const tag_macro_defs: uint = 0xb5;
+pub const tag_macro_def: uint = 0xb6;
+pub const tag_macro_def_body: uint = 0xb7;
index b0cf322b0688ec47baa287ca59477d45f88e7306..171bfd74a816b4604c281b7ac1933a002d453447 100644 (file)
 use session::{config, Session};
 use session::search_paths::PathKind;
 use metadata::cstore;
-use metadata::cstore::{CStore, CrateSource};
+use metadata::cstore::{CStore, CrateSource, MetadataBlob};
 use metadata::decoder;
 use metadata::loader;
 use metadata::loader::CratePaths;
-use plugin::load::PluginMetadata;
 use util::nodemap::FnvHashMap;
 
 use std::rc::Rc;
 use syntax::abi;
 use syntax::attr;
 use syntax::attr::AttrMetaMethods;
-use syntax::codemap::{Span};
+use syntax::codemap::{Span, mk_sp};
 use syntax::diagnostic::SpanHandler;
+use syntax::parse;
 use syntax::parse::token::InternedString;
 use syntax::parse::token;
 use syntax::visit;
 use util::fs;
+use log;
 
-struct Env<'a> {
+pub struct CrateReader<'a> {
     sess: &'a Session,
     next_crate_num: ast::CrateNum,
 }
 
-// Traverses an AST, reading all the information about use'd crates and extern
-// libraries necessary for later resolving, typechecking, linking, etc.
-pub fn read_crates(sess: &Session,
-                   krate: &ast::Crate) {
-    let mut e = Env {
-        sess: sess,
-        next_crate_num: sess.cstore.next_crate_num(),
-    };
-    visit_crate(&e, krate);
-    visit::walk_crate(&mut e, krate);
-    dump_crates(&sess.cstore);
-    warn_if_multiple_versions(sess.diagnostic(), &sess.cstore);
-
-    for &(ref name, kind) in sess.opts.libs.iter() {
-        register_native_lib(sess, None, name.clone(), kind);
-    }
-}
-
-impl<'a, 'v> visit::Visitor<'v> for Env<'a> {
+impl<'a, 'v> visit::Visitor<'v> for CrateReader<'a> {
     fn visit_view_item(&mut self, a: &ast::ViewItem) {
-        visit_view_item(self, a);
+        self.process_view_item(a);
         visit::walk_view_item(self, a);
     }
     fn visit_item(&mut self, a: &ast::Item) {
-        visit_item(self, a);
+        self.process_item(a);
         visit::walk_item(self, a);
     }
 }
@@ -105,42 +88,8 @@ fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) {
     }
 }
 
-fn visit_crate(e: &Env, c: &ast::Crate) {
-    for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
-        match a.value_str() {
-            Some(ref linkarg) => e.sess.cstore.add_used_link_args(linkarg.get()),
-            None => { /* fallthrough */ }
-        }
-    }
-}
-
 fn should_link(i: &ast::ViewItem) -> bool {
-    i.attrs.iter().all(|attr| {
-        attr.name().get() != "phase" ||
-            attr.meta_item_list().map_or(false, |phases| {
-                attr::contains_name(phases[], "link")
-            })
-    })
-}
-
-fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
-    if !should_link(i) {
-        return;
-    }
-
-    match extract_crate_info(e, i) {
-        Some(info) => {
-            let (cnum, _, _) = resolve_crate(e,
-                                             &None,
-                                             info.ident[],
-                                             info.name[],
-                                             None,
-                                             i.span,
-                                             PathKind::Crate);
-            e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
-        }
-        None => ()
-    }
+    !attr::contains_name(i.attrs[], "no_link")
 }
 
 struct CrateInfo {
@@ -150,32 +99,6 @@ struct CrateInfo {
     should_link: bool,
 }
 
-fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
-    match i.node {
-        ast::ViewItemExternCrate(ident, ref path_opt, id) => {
-            let ident = token::get_ident(ident);
-            debug!("resolving extern crate stmt. ident: {} path_opt: {}",
-                   ident, path_opt);
-            let name = match *path_opt {
-                Some((ref path_str, _)) => {
-                    let name = path_str.get().to_string();
-                    validate_crate_name(Some(e.sess), name[],
-                                        Some(i.span));
-                    name
-                }
-                None => ident.get().to_string(),
-            };
-            Some(CrateInfo {
-                ident: ident.get().to_string(),
-                name: name,
-                id: id,
-                should_link: should_link(i),
-            })
-        }
-        _ => None
-    }
-}
-
 pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
     let err = |&: s: &str| {
         match (sp, sess) {
@@ -198,85 +121,6 @@ pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
     }
 }
 
-fn visit_item(e: &Env, i: &ast::Item) {
-    match i.node {
-        ast::ItemForeignMod(ref fm) => {
-            if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
-                return;
-            }
-
-            // First, add all of the custom link_args attributes
-            let link_args = i.attrs.iter()
-                .filter_map(|at| if at.name() == "link_args" {
-                    Some(at)
-                } else {
-                    None
-                })
-                .collect::<Vec<&ast::Attribute>>();
-            for m in link_args.iter() {
-                match m.value_str() {
-                    Some(linkarg) => e.sess.cstore.add_used_link_args(linkarg.get()),
-                    None => { /* fallthrough */ }
-                }
-            }
-
-            // Next, process all of the #[link(..)]-style arguments
-            let link_args = i.attrs.iter()
-                .filter_map(|at| if at.name() == "link" {
-                    Some(at)
-                } else {
-                    None
-                })
-                .collect::<Vec<&ast::Attribute>>();
-            for m in link_args.iter() {
-                match m.meta_item_list() {
-                    Some(items) => {
-                        let kind = items.iter().find(|k| {
-                            k.name() == "kind"
-                        }).and_then(|a| a.value_str());
-                        let kind = match kind {
-                            Some(k) => {
-                                if k == "static" {
-                                    cstore::NativeStatic
-                                } else if e.sess.target.target.options.is_like_osx
-                                          && k == "framework" {
-                                    cstore::NativeFramework
-                                } else if k == "framework" {
-                                    cstore::NativeFramework
-                                } else if k == "dylib" {
-                                    cstore::NativeUnknown
-                                } else {
-                                    e.sess.span_err(m.span,
-                                        format!("unknown kind: `{}`",
-                                                k)[]);
-                                    cstore::NativeUnknown
-                                }
-                            }
-                            None => cstore::NativeUnknown
-                        };
-                        let n = items.iter().find(|n| {
-                            n.name() == "name"
-                        }).and_then(|a| a.value_str());
-                        let n = match n {
-                            Some(n) => n,
-                            None => {
-                                e.sess.span_err(m.span,
-                                    "#[link(...)] specified without \
-                                     `name = \"foo\"`");
-                                InternedString::new("foo")
-                            }
-                        };
-                        register_native_lib(e.sess, Some(m.span),
-                                            n.get().to_string(), kind);
-                    }
-                    None => {}
-                }
-            }
-        }
-        _ => { }
-    }
-}
-
 fn register_native_lib(sess: &Session,
                        span: Option<Span>,
                        name: String,
@@ -304,172 +148,341 @@ fn register_native_lib(sess: &Session,
     sess.cstore.add_used_library(name, kind);
 }
 
-fn existing_match(e: &Env, name: &str,
-                  hash: Option<&Svh>) -> Option<ast::CrateNum> {
-    let mut ret = None;
-    e.sess.cstore.iter_crate_data(|cnum, data| {
-        if data.name != name { return }
+pub struct PluginMetadata<'a> {
+    sess: &'a Session,
+    metadata: PMDSource,
+    dylib: Option<Path>,
+    info: CrateInfo,
+    vi_span: Span,
+    target_only: bool,
+}
 
-        match hash {
-            Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
-            Some(..) => return,
-            None => {}
-        }
+enum PMDSource {
+    Registered(Rc<cstore::crate_metadata>),
+    Owned(MetadataBlob),
+}
 
-        // When the hash is None we're dealing with a top-level dependency in
-        // which case we may have a specification on the command line for this
-        // library. Even though an upstream library may have loaded something of
-        // the same name, we have to make sure it was loaded from the exact same
-        // location as well.
-        //
-        // We're also sure to compare *paths*, not actual byte slices. The
-        // `source` stores paths which are normalized which may be different
-        // from the strings on the command line.
-        let source = e.sess.cstore.get_used_crate_source(cnum).unwrap();
-        match e.sess.opts.externs.get(name) {
-            Some(locs) => {
-                let found = locs.iter().any(|l| {
-                    let l = fs::realpath(&Path::new(l[])).ok();
-                    l == source.dylib || l == source.rlib
-                });
-                if found {
-                    ret = Some(cnum);
-                }
-            }
-            None => ret = Some(cnum),
+impl PMDSource {
+    pub fn as_slice<'a>(&'a self) -> &'a [u8] {
+        match *self {
+            PMDSource::Registered(ref cmd) => cmd.data(),
+            PMDSource::Owned(ref mdb) => mdb.as_slice(),
         }
-    });
-    return ret;
+    }
 }
 
-fn register_crate<'a>(e: &mut Env,
-                  root: &Option<CratePaths>,
-                  ident: &str,
-                  name: &str,
-                  span: Span,
-                  lib: loader::Library)
-                        -> (ast::CrateNum, Rc<cstore::crate_metadata>,
-                            cstore::CrateSource) {
-    // Claim this crate number and cache it
-    let cnum = e.next_crate_num;
-    e.next_crate_num += 1;
-
-    // Stash paths for top-most crate locally if necessary.
-    let crate_paths = if root.is_none() {
-        Some(CratePaths {
-            ident: ident.to_string(),
-            dylib: lib.dylib.clone(),
-            rlib:  lib.rlib.clone(),
-        })
-    } else {
-        None
-    };
-    // Maintain a reference to the top most crate.
-    let root = if root.is_some() { root } else { &crate_paths };
+impl<'a> CrateReader<'a> {
+    pub fn new(sess: &'a Session) -> CrateReader<'a> {
+        CrateReader {
+            sess: sess,
+            next_crate_num: sess.cstore.next_crate_num(),
+        }
+    }
 
-    let cnum_map = resolve_crate_deps(e, root, lib.metadata.as_slice(), span);
+    // Traverses an AST, reading all the information about use'd crates and extern
+    // libraries necessary for later resolving, typechecking, linking, etc.
+    pub fn read_crates(&mut self, krate: &ast::Crate) {
+        self.process_crate(krate);
+        visit::walk_crate(self, krate);
 
-    let loader::Library{ dylib, rlib, metadata } = lib;
+        if log_enabled!(log::DEBUG) {
+            dump_crates(&self.sess.cstore);
+        }
+        warn_if_multiple_versions(self.sess.diagnostic(), &self.sess.cstore);
 
-    let cmeta = Rc::new( cstore::crate_metadata {
-        name: name.to_string(),
-        data: metadata,
-        cnum_map: cnum_map,
-        cnum: cnum,
-        span: span,
-    });
+        for &(ref name, kind) in self.sess.opts.libs.iter() {
+            register_native_lib(self.sess, None, name.clone(), kind);
+        }
+    }
 
-    let source = cstore::CrateSource {
-        dylib: dylib,
-        rlib: rlib,
-        cnum: cnum,
-    };
+    fn process_crate(&self, c: &ast::Crate) {
+        for a in c.attrs.iter().filter(|m| m.name() == "link_args") {
+            match a.value_str() {
+                Some(ref linkarg) => self.sess.cstore.add_used_link_args(linkarg.get()),
+                None => { /* fallthrough */ }
+            }
+        }
+    }
 
-    e.sess.cstore.set_crate_data(cnum, cmeta.clone());
-    e.sess.cstore.add_used_crate_source(source.clone());
-    (cnum, cmeta, source)
-}
+    fn process_view_item(&mut self, i: &ast::ViewItem) {
+        if !should_link(i) {
+            return;
+        }
 
-fn resolve_crate(e: &mut Env,
-                 root: &Option<CratePaths>,
-                 ident: &str,
-                 name: &str,
-                 hash: Option<&Svh>,
-                 span: Span,
-                 kind: PathKind)
-                     -> (ast::CrateNum, Rc<cstore::crate_metadata>,
-                         cstore::CrateSource) {
-    match existing_match(e, name, hash) {
-        None => {
-            let mut load_ctxt = loader::Context {
-                sess: e.sess,
-                span: span,
-                ident: ident,
-                crate_name: name,
-                hash: hash.map(|a| &*a),
-                filesearch: e.sess.target_filesearch(kind),
-                triple: e.sess.opts.target_triple[],
-                root: root,
-                rejected_via_hash: vec!(),
-                rejected_via_triple: vec!(),
-                should_match_name: true,
-            };
-            let library = load_ctxt.load_library_crate();
-            register_crate(e, root, ident, name, span, library)
+        match self.extract_crate_info(i) {
+            Some(info) => {
+                let (cnum, _, _) = self.resolve_crate(&None,
+                                                      info.ident[],
+                                                      info.name[],
+                                                      None,
+                                                      i.span,
+                                                      PathKind::Crate);
+                self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
+            }
+            None => ()
         }
-        Some(cnum) => (cnum,
-                       e.sess.cstore.get_crate_data(cnum),
-                       e.sess.cstore.get_used_crate_source(cnum).unwrap())
     }
-}
 
-// Go through the crate metadata and load any crates that it references
-fn resolve_crate_deps(e: &mut Env,
+    fn extract_crate_info(&self, i: &ast::ViewItem) -> Option<CrateInfo> {
+        match i.node {
+            ast::ViewItemExternCrate(ident, ref path_opt, id) => {
+                let ident = token::get_ident(ident);
+                debug!("resolving extern crate stmt. ident: {} path_opt: {}",
+                       ident, path_opt);
+                let name = match *path_opt {
+                    Some((ref path_str, _)) => {
+                        let name = path_str.get().to_string();
+                        validate_crate_name(Some(self.sess), name[],
+                                            Some(i.span));
+                        name
+                    }
+                    None => ident.get().to_string(),
+                };
+                Some(CrateInfo {
+                    ident: ident.get().to_string(),
+                    name: name,
+                    id: id,
+                    should_link: should_link(i),
+                })
+            }
+            _ => None
+        }
+    }
+
+    fn process_item(&self, i: &ast::Item) {
+        match i.node {
+            ast::ItemForeignMod(ref fm) => {
+                if fm.abi == abi::Rust || fm.abi == abi::RustIntrinsic {
+                    return;
+                }
+
+                // First, add all of the custom link_args attributes
+                let link_args = i.attrs.iter()
+                    .filter_map(|at| if at.name() == "link_args" {
+                        Some(at)
+                    } else {
+                        None
+                    })
+                    .collect::<Vec<&ast::Attribute>>();
+                for m in link_args.iter() {
+                    match m.value_str() {
+                        Some(linkarg) => self.sess.cstore.add_used_link_args(linkarg.get()),
+                        None => { /* fallthrough */ }
+                    }
+                }
+
+                // Next, process all of the #[link(..)]-style arguments
+                let link_args = i.attrs.iter()
+                    .filter_map(|at| if at.name() == "link" {
+                        Some(at)
+                    } else {
+                        None
+                    })
+                    .collect::<Vec<&ast::Attribute>>();
+                for m in link_args.iter() {
+                    match m.meta_item_list() {
+                        Some(items) => {
+                            let kind = items.iter().find(|k| {
+                                k.name() == "kind"
+                            }).and_then(|a| a.value_str());
+                            let kind = match kind {
+                                Some(k) => {
+                                    if k == "static" {
+                                        cstore::NativeStatic
+                                    } else if self.sess.target.target.options.is_like_osx
+                                              && k == "framework" {
+                                        cstore::NativeFramework
+                                    } else if k == "framework" {
+                                        cstore::NativeFramework
+                                    } else if k == "dylib" {
+                                        cstore::NativeUnknown
+                                    } else {
+                                        self.sess.span_err(m.span,
+                                            format!("unknown kind: `{}`",
+                                                    k)[]);
+                                        cstore::NativeUnknown
+                                    }
+                                }
+                                None => cstore::NativeUnknown
+                            };
+                            let n = items.iter().find(|n| {
+                                n.name() == "name"
+                            }).and_then(|a| a.value_str());
+                            let n = match n {
+                                Some(n) => n,
+                                None => {
+                                    self.sess.span_err(m.span,
+                                        "#[link(...)] specified without \
+                                         `name = \"foo\"`");
+                                    InternedString::new("foo")
+                                }
+                            };
+                            register_native_lib(self.sess, Some(m.span),
+                                                n.get().to_string(), kind);
+                        }
+                        None => {}
+                    }
+                }
+            }
+            _ => { }
+        }
+    }
+
+    fn existing_match(&self, name: &str,
+                      hash: Option<&Svh>) -> Option<ast::CrateNum> {
+        let mut ret = None;
+        self.sess.cstore.iter_crate_data(|cnum, data| {
+            if data.name != name { return }
+
+            match hash {
+                Some(hash) if *hash == data.hash() => { ret = Some(cnum); return }
+                Some(..) => return,
+                None => {}
+            }
+
+            // When the hash is None we're dealing with a top-level dependency in
+            // which case we may have a specification on the command line for this
+            // library. Even though an upstream library may have loaded something of
+            // the same name, we have to make sure it was loaded from the exact same
+            // location as well.
+            //
+            // We're also sure to compare *paths*, not actual byte slices. The
+            // `source` stores paths which are normalized which may be different
+            // from the strings on the command line.
+            let source = self.sess.cstore.get_used_crate_source(cnum).unwrap();
+            match self.sess.opts.externs.get(name) {
+                Some(locs) => {
+                    let found = locs.iter().any(|l| {
+                        let l = fs::realpath(&Path::new(l[])).ok();
+                        l == source.dylib || l == source.rlib
+                    });
+                    if found {
+                        ret = Some(cnum);
+                    }
+                }
+                None => ret = Some(cnum),
+            }
+        });
+        return ret;
+    }
+
+    fn register_crate(&mut self,
                       root: &Option<CratePaths>,
-                      cdata: &[u8], span : Span)
-                   -> cstore::cnum_map {
-    debug!("resolving deps of external crate");
-    // The map from crate numbers in the crate we're resolving to local crate
-    // numbers
-    decoder::get_crate_deps(cdata).iter().map(|dep| {
-        debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
-        let (local_cnum, _, _) = resolve_crate(e, root,
-                                               dep.name[],
-                                               dep.name[],
-                                               Some(&dep.hash),
-                                               span,
-                                               PathKind::Dependency);
-        (dep.cnum, local_cnum)
-    }).collect()
-}
+                      ident: &str,
+                      name: &str,
+                      span: Span,
+                      lib: loader::Library)
+                      -> (ast::CrateNum, Rc<cstore::crate_metadata>,
+                          cstore::CrateSource) {
+        // Claim this crate number and cache it
+        let cnum = self.next_crate_num;
+        self.next_crate_num += 1;
+
+        // Stash paths for top-most crate locally if necessary.
+        let crate_paths = if root.is_none() {
+            Some(CratePaths {
+                ident: ident.to_string(),
+                dylib: lib.dylib.clone(),
+                rlib:  lib.rlib.clone(),
+            })
+        } else {
+            None
+        };
+        // Maintain a reference to the top most crate.
+        let root = if root.is_some() { root } else { &crate_paths };
 
-pub struct PluginMetadataReader<'a> {
-    env: Env<'a>,
-}
+        let cnum_map = self.resolve_crate_deps(root, lib.metadata.as_slice(), span);
+
+        let loader::Library{ dylib, rlib, metadata } = lib;
+
+        let cmeta = Rc::new( cstore::crate_metadata {
+            name: name.to_string(),
+            data: metadata,
+            cnum_map: cnum_map,
+            cnum: cnum,
+            span: span,
+        });
+
+        let source = cstore::CrateSource {
+            dylib: dylib,
+            rlib: rlib,
+            cnum: cnum,
+        };
+
+        self.sess.cstore.set_crate_data(cnum, cmeta.clone());
+        self.sess.cstore.add_used_crate_source(source.clone());
+        (cnum, cmeta, source)
+    }
 
-impl<'a> PluginMetadataReader<'a> {
-    pub fn new(sess: &'a Session) -> PluginMetadataReader<'a> {
-        PluginMetadataReader {
-            env: Env {
-                sess: sess,
-                next_crate_num: sess.cstore.next_crate_num(),
+    fn resolve_crate(&mut self,
+                     root: &Option<CratePaths>,
+                     ident: &str,
+                     name: &str,
+                     hash: Option<&Svh>,
+                     span: Span,
+                     kind: PathKind)
+                         -> (ast::CrateNum, Rc<cstore::crate_metadata>,
+                             cstore::CrateSource) {
+        match self.existing_match(name, hash) {
+            None => {
+                let mut load_ctxt = loader::Context {
+                    sess: self.sess,
+                    span: span,
+                    ident: ident,
+                    crate_name: name,
+                    hash: hash.map(|a| &*a),
+                    filesearch: self.sess.target_filesearch(kind),
+                    triple: self.sess.opts.target_triple[],
+                    root: root,
+                    rejected_via_hash: vec!(),
+                    rejected_via_triple: vec!(),
+                    should_match_name: true,
+                };
+                let library = load_ctxt.load_library_crate();
+                self.register_crate(root, ident, name, span, library)
             }
+            Some(cnum) => (cnum,
+                           self.sess.cstore.get_crate_data(cnum),
+                           self.sess.cstore.get_used_crate_source(cnum).unwrap())
         }
     }
 
-    pub fn read_plugin_metadata(&mut self,
-                                krate: &ast::ViewItem) -> PluginMetadata {
-        let info = extract_crate_info(&self.env, krate).unwrap();
-        let target_triple = self.env.sess.opts.target_triple[];
+    // Go through the crate metadata and load any crates that it references
+    fn resolve_crate_deps(&mut self,
+                          root: &Option<CratePaths>,
+                          cdata: &[u8], span : Span)
+                       -> cstore::cnum_map {
+        debug!("resolving deps of external crate");
+        // The map from crate numbers in the crate we're resolving to local crate
+        // numbers
+        decoder::get_crate_deps(cdata).iter().map(|dep| {
+            debug!("resolving dep crate {} hash: `{}`", dep.name, dep.hash);
+            let (local_cnum, _, _) = self.resolve_crate(root,
+                                                   dep.name[],
+                                                   dep.name[],
+                                                   Some(&dep.hash),
+                                                   span,
+                                                   PathKind::Dependency);
+            (dep.cnum, local_cnum)
+        }).collect()
+    }
+
+    pub fn read_plugin_metadata<'b>(&'b mut self,
+                                    vi: &'b ast::ViewItem) -> PluginMetadata<'b> {
+        let info = self.extract_crate_info(vi).unwrap();
+        let target_triple = self.sess.opts.target_triple[];
         let is_cross = target_triple != config::host_triple();
         let mut should_link = info.should_link && !is_cross;
+        let mut target_only = false;
+        let ident = info.ident.clone();
+        let name = info.name.clone();
         let mut load_ctxt = loader::Context {
-            sess: self.env.sess,
-            span: krate.span,
-            ident: info.ident[],
-            crate_name: info.name[],
+            sess: self.sess,
+            span: vi.span,
+            ident: ident[],
+            crate_name: name[],
             hash: None,
-            filesearch: self.env.sess.host_filesearch(PathKind::Crate),
+            filesearch: self.sess.host_filesearch(PathKind::Crate),
             triple: config::host_triple(),
             root: &None,
             rejected_via_hash: vec!(),
@@ -479,49 +492,106 @@ pub fn read_plugin_metadata(&mut self,
         let library = match load_ctxt.maybe_load_library_crate() {
             Some(l) => l,
             None if is_cross => {
-                // try loading from target crates (only valid if there are
-                // no syntax extensions)
-                load_ctxt.triple = target_triple;
-                load_ctxt.filesearch = self.env.sess.target_filesearch(PathKind::Crate);
-                let lib = load_ctxt.load_library_crate();
-                if decoder::get_plugin_registrar_fn(lib.metadata.as_slice()).is_some() {
-                    let message = format!("crate `{}` contains a plugin_registrar fn but \
-                                  only a version for triple `{}` could be found (need {})",
-                                  info.ident, target_triple, config::host_triple());
-                    self.env.sess.span_err(krate.span, message[]);
-                    // need to abort now because the syntax expansion
-                    // code will shortly attempt to load and execute
-                    // code from the found library.
-                    self.env.sess.abort_if_errors();
-                }
+                // Try loading from target crates. This will abort later if we try to
+                // load a plugin registrar function,
+                target_only = true;
                 should_link = info.should_link;
-                lib
+
+                load_ctxt.triple = target_triple;
+                load_ctxt.filesearch = self.sess.target_filesearch(PathKind::Crate);
+                load_ctxt.load_library_crate()
             }
             None => { load_ctxt.report_load_errs(); unreachable!() },
         };
-        let macros = decoder::get_exported_macros(library.metadata.as_slice());
-        let registrar = decoder::get_plugin_registrar_fn(library.metadata.as_slice()).map(|id| {
-            decoder::get_symbol(library.metadata.as_slice(), id)
-        });
-        if library.dylib.is_none() && registrar.is_some() {
-            let message = format!("plugin crate `{}` only found in rlib format, \
-                                   but must be available in dylib format",
-                                  info.ident);
-            self.env.sess.span_err(krate.span, message[]);
-            // No need to abort because the loading code will just ignore this
-            // empty dylib.
-        }
-        let pc = PluginMetadata {
-            lib: library.dylib.clone(),
-            macros: macros,
-            registrar_symbol: registrar,
+
+        let dylib = library.dylib.clone();
+        let register = should_link && self.existing_match(info.name[], None).is_none();
+        let metadata = if register {
+            // Register crate now to avoid double-reading metadata
+            let (_, cmd, _) = self.register_crate(&None, info.ident[],
+                                info.name[], vi.span, library);
+            PMDSource::Registered(cmd)
+        } else {
+            // Not registering the crate; just hold on to the metadata
+            PMDSource::Owned(library.metadata)
         };
-        if should_link && existing_match(&self.env, info.name[],
-                                         None).is_none() {
-            // register crate now to avoid double-reading metadata
-            register_crate(&mut self.env, &None, info.ident[],
-                           info.name[], krate.span, library);
+
+        PluginMetadata {
+            sess: self.sess,
+            metadata: metadata,
+            dylib: dylib,
+            info: info,
+            vi_span: vi.span,
+            target_only: target_only,
+        }
+    }
+}
+
+impl<'a> PluginMetadata<'a> {
+    /// Read exported macros
+    pub fn exported_macros(&self) -> Vec<ast::MacroDef> {
+        let imported_from = Some(token::intern(self.info.ident[]).ident());
+        let source_name = format!("<{} macros>", self.info.ident[]);
+        let mut macros = vec![];
+        decoder::each_exported_macro(self.metadata.as_slice(),
+                                     &*self.sess.cstore.intr,
+            |name, attrs, body| {
+                // NB: Don't use parse::parse_tts_from_source_str because it parses with
+                // quote_depth > 0.
+                let mut p = parse::new_parser_from_source_str(&self.sess.parse_sess,
+                                                              self.sess.opts.cfg.clone(),
+                                                              source_name.clone(),
+                                                              body);
+                let lo = p.span.lo;
+                let body = p.parse_all_token_trees();
+                let span = mk_sp(lo, p.last_span.hi);
+                p.abort_if_errors();
+                macros.push(ast::MacroDef {
+                    ident: name.ident(),
+                    attrs: attrs,
+                    id: ast::DUMMY_NODE_ID,
+                    span: span,
+                    imported_from: imported_from,
+                    // overridden in plugin/load.rs
+                    export: false,
+                    use_locally: false,
+
+                    body: body,
+                });
+                true
+            }
+        );
+        macros
+    }
+
+    /// Look for a plugin registrar. Returns library path and symbol name.
+    pub fn plugin_registrar(&self) -> Option<(Path, String)> {
+        if self.target_only {
+            // Need to abort before syntax expansion.
+            let message = format!("plugin crate `{}` is not available for triple `{}` \
+                                   (only found {})",
+                                  self.info.ident,
+                                  config::host_triple(),
+                                  self.sess.opts.target_triple);
+            self.sess.span_err(self.vi_span, message[]);
+            self.sess.abort_if_errors();
+        }
+
+        let registrar = decoder::get_plugin_registrar_fn(self.metadata.as_slice())
+            .map(|id| decoder::get_symbol(self.metadata.as_slice(), id));
+
+        match (self.dylib.as_ref(), registrar) {
+            (Some(dylib), Some(reg)) => Some((dylib.clone(), reg)),
+            (None, Some(_)) => {
+                let message = format!("plugin crate `{}` only found in rlib format, \
+                                       but must be available in dylib format",
+                                       self.info.ident);
+                self.sess.span_err(self.vi_span, message[]);
+                // No need to abort because the loading code will just ignore this
+                // empty dylib.
+                None
+            }
+            _ => None,
         }
-        pc
     }
 }
index ac8dfc1675942c37055147762cb438bb94a20568..ed0a1f6211b16edd5cc56be5cf8c7321e340c51d 100644 (file)
@@ -1353,15 +1353,16 @@ pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
         .map(|doc| FromPrimitive::from_u32(reader::doc_as_u32(doc)).unwrap())
 }
 
-pub fn get_exported_macros(data: &[u8]) -> Vec<String> {
-    let macros = reader::get_doc(rbml::Doc::new(data),
-                                 tag_exported_macros);
-    let mut result = Vec::new();
+pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
+    F: FnMut(ast::Name, Vec<ast::Attribute>, String) -> bool,
+{
+    let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs);
     reader::tagged_docs(macros, tag_macro_def, |macro_doc| {
-        result.push(macro_doc.as_str().to_string());
-        true
+        let name = item_name(intr, macro_doc);
+        let attrs = get_attributes(macro_doc);
+        let body = reader::get_doc(macro_doc, tag_macro_def_body);
+        f(name, attrs, body.as_str().to_string())
     });
-    result
 }
 
 pub fn get_dylib_dependency_formats(cdata: Cmd)
index 14ab471a4b8314c77fd4c626f9dfbca4c44ed939..e4226ddde85b6540c0a6bd78e255e16420a46729 100644 (file)
@@ -42,6 +42,7 @@
 use syntax::diagnostic::SpanHandler;
 use syntax::parse::token::special_idents;
 use syntax::parse::token;
+use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::visit::Visitor;
 use syntax::visit;
@@ -1817,25 +1818,21 @@ fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) {
     }
 }
 
-/// Given a span, write the text of that span into the output stream
-/// as an exported macro
-fn encode_macro_def(ecx: &EncodeContext,
-                    rbml_w: &mut Encoder,
-                    span: &syntax::codemap::Span) {
-    let def = ecx.tcx.sess.codemap().span_to_snippet(*span)
-        .expect("Unable to find source for macro");
-    rbml_w.start_tag(tag_macro_def);
-    rbml_w.wr_str(def[]);
-    rbml_w.end_tag();
-}
-
 /// Serialize the text of the exported macros
-fn encode_macro_defs(ecx: &EncodeContext,
-                     krate: &ast::Crate,
-                     rbml_w: &mut Encoder) {
-    rbml_w.start_tag(tag_exported_macros);
-    for item in krate.exported_macros.iter() {
-        encode_macro_def(ecx, rbml_w, &item.span);
+fn encode_macro_defs(rbml_w: &mut Encoder,
+                     krate: &ast::Crate) {
+    rbml_w.start_tag(tag_macro_defs);
+    for def in krate.exported_macros.iter() {
+        rbml_w.start_tag(tag_macro_def);
+
+        encode_name(rbml_w, def.ident.name);
+        encode_attributes(rbml_w, def.attrs[]);
+
+        rbml_w.start_tag(tag_macro_def_body);
+        rbml_w.wr_str(pprust::tts_to_string(def.body[])[]);
+        rbml_w.end_tag();
+
+        rbml_w.end_tag();
     }
     rbml_w.end_tag();
 }
@@ -2153,7 +2150,7 @@ struct Stats {
 
     // Encode macro definitions
     i = rbml_w.writer.tell().unwrap();
-    encode_macro_defs(&ecx, krate, &mut rbml_w);
+    encode_macro_defs(&mut rbml_w, krate);
     stats.macro_defs_bytes = rbml_w.writer.tell().unwrap() - i;
 
     // Encode the types of all unboxed closures in this crate.
index a95523f2e06005f3f72af857d4a8bd0dc1e6e788..32482fce4daa8b05d556f35333e724f4980937cb 100644 (file)
@@ -503,7 +503,7 @@ fn fromb(b: bool) -> Result<const_val, String> { Ok(const_int(b as i64)) }
                                         "target type not found for const cast")
                 });
 
-        macro_rules! define_casts(
+        macro_rules! define_casts {
             ($val:ident, {
                 $($ty_pat:pat => (
                     $intermediate_ty:ty,
@@ -524,7 +524,7 @@ macro_rules! define_casts(
                 },)*
                 _ => Err("can't cast this type".to_string())
             })
-        );
+        }
 
         eval_const_expr_partial(tcx, &**base)
             .and_then(|val| define_casts!(val, {
index 291bb4c982058df82cb96ae044c97de0b73d20ae..c359233eca173cd4ad7b9fe05d76b6838a4bc6d4 100644 (file)
@@ -6171,8 +6171,8 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
     return state.result();
 
     fn helper<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh, state: &mut sip::SipState) {
-        macro_rules! byte( ($b:expr) => { ($b as u8).hash(state) } );
-        macro_rules! hash( ($e:expr) => { $e.hash(state) } );
+        macro_rules! byte { ($b:expr) => { ($b as u8).hash(state) } }
+        macro_rules! hash { ($e:expr) => { $e.hash(state) }  }
 
         let region = |&: state: &mut sip::SipState, r: Region| {
             match r {
index a2e334543206cc68ea6ed35e75639b9f3f64e246..44a223954858a76d7089143c981353b2a72a705a 100644 (file)
@@ -8,47 +8,46 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! Used by `rustc` when loading a plugin.
+//! Used by `rustc` when loading a plugin, or a crate with exported macros.
 
 use session::Session;
-use metadata::creader::PluginMetadataReader;
+use metadata::creader::CrateReader;
 use plugin::registry::Registry;
 
 use std::mem;
 use std::os;
 use std::dynamic_lib::DynamicLibrary;
+use std::collections::HashSet;
 use syntax::ast;
 use syntax::attr;
+use syntax::codemap::Span;
+use syntax::parse::token;
+use syntax::ptr::P;
 use syntax::visit;
 use syntax::visit::Visitor;
-use syntax::ext::expand::ExportedMacros;
 use syntax::attr::AttrMetaMethods;
 
-/// Plugin-related crate metadata.
-pub struct PluginMetadata {
-    /// Source code of macros exported by the crate.
-    pub macros: Vec<String>,
-    /// Path to the shared library file.
-    pub lib: Option<Path>,
-    /// Symbol name of the plugin registrar function.
-    pub registrar_symbol: Option<String>,
-}
-
 /// Pointer to a registrar function.
 pub type PluginRegistrarFun =
     fn(&mut Registry);
 
+pub struct PluginRegistrar {
+    pub fun: PluginRegistrarFun,
+    pub args: P<ast::MetaItem>,
+}
+
 /// Information about loaded plugins.
 pub struct Plugins {
-    /// Source code of exported macros.
-    pub macros: Vec<ExportedMacros>,
+    /// Imported macros.
+    pub macros: Vec<ast::MacroDef>,
     /// Registrars, as function pointers.
-    pub registrars: Vec<PluginRegistrarFun>,
+    pub registrars: Vec<PluginRegistrar>,
 }
 
 struct PluginLoader<'a> {
     sess: &'a Session,
-    reader: PluginMetadataReader<'a>,
+    span_whitelist: HashSet<Span>,
+    reader: CrateReader<'a>,
     plugins: Plugins,
 }
 
@@ -56,7 +55,8 @@ impl<'a> PluginLoader<'a> {
     fn new(sess: &'a Session) -> PluginLoader<'a> {
         PluginLoader {
             sess: sess,
-            reader: PluginMetadataReader::new(sess),
+            reader: CrateReader::new(sess),
+            span_whitelist: HashSet::new(),
             plugins: Plugins {
                 macros: vec!(),
                 registrars: vec!(),
@@ -69,6 +69,14 @@ fn new(sess: &'a Session) -> PluginLoader<'a> {
 pub fn load_plugins(sess: &Session, krate: &ast::Crate,
                     addl_plugins: Option<Plugins>) -> Plugins {
     let mut loader = PluginLoader::new(sess);
+
+    // We need to error on `#[macro_use] extern crate` when it isn't at the
+    // crate root, because `$crate` won't work properly. Identify these by
+    // spans, because the crate map isn't set up yet.
+    for vi in krate.module.view_items.iter() {
+        loader.span_whitelist.insert(vi.span);
+    }
+
     visit::walk_crate(&mut loader, krate);
 
     let mut plugins = loader.plugins;
@@ -89,41 +97,112 @@ pub fn load_plugins(sess: &Session, krate: &ast::Crate,
 // note that macros aren't expanded yet, and therefore macros can't add plugins.
 impl<'a, 'v> Visitor<'v> for PluginLoader<'a> {
     fn visit_view_item(&mut self, vi: &ast::ViewItem) {
+        // We're only interested in `extern crate`.
         match vi.node {
-            ast::ViewItemExternCrate(name, _, _) => {
-                let mut plugin_phase = false;
+            ast::ViewItemExternCrate(..) => (),
+            _ => return,
+        }
 
-                for attr in vi.attrs.iter().filter(|a| a.check_name("phase")) {
-                    let phases = attr.meta_item_list().unwrap_or(&[]);
-                    if attr::contains_name(phases, "plugin") {
-                        plugin_phase = true;
+        // Parse the attributes relating to macro / plugin loading.
+        let mut plugin_attr = None;
+        let mut macro_selection = Some(HashSet::new());  // None => load all
+        let mut reexport = HashSet::new();
+        for attr in vi.attrs.iter() {
+            let mut used = true;
+            match attr.name().get() {
+                "phase" => {
+                    self.sess.span_err(attr.span, "#[phase] is deprecated; use \
+                                       #[macro_use], #[plugin], and/or #[no_link]");
+                }
+                "plugin" => {
+                    if plugin_attr.is_some() {
+                        self.sess.span_err(attr.span, "#[plugin] specified multiple times");
+                    }
+                    plugin_attr = Some(attr.node.value.clone());
+                }
+                "macro_use" => {
+                    let names = attr.meta_item_list();
+                    if names.is_none() {
+                        // no names => load all
+                        macro_selection = None;
+                    }
+                    if let (Some(sel), Some(names)) = (macro_selection.as_mut(), names) {
+                        for name in names.iter() {
+                            if let ast::MetaWord(ref name) = name.node {
+                                sel.insert(name.clone());
+                            } else {
+                                self.sess.span_err(name.span, "bad macro import");
+                            }
+                        }
                     }
-                    if attr::contains_name(phases, "syntax") {
-                        plugin_phase = true;
-                        self.sess.span_warn(attr.span,
-                            "phase(syntax) is a deprecated synonym for phase(plugin)");
+                }
+                "macro_reexport" => {
+                    let names = match attr.meta_item_list() {
+                        Some(names) => names,
+                        None => {
+                            self.sess.span_err(attr.span, "bad macro reexport");
+                            continue;
+                        }
+                    };
+
+                    for name in names.iter() {
+                        if let ast::MetaWord(ref name) = name.node {
+                            reexport.insert(name.clone());
+                        } else {
+                            self.sess.span_err(name.span, "bad macro reexport");
+                        }
                     }
                 }
+                _ => used = false,
+            }
+            if used {
+                attr::mark_used(attr);
+            }
+        }
 
-                if !plugin_phase { return; }
+        let mut macros = vec![];
+        let mut registrar = None;
 
-                let PluginMetadata { macros, lib, registrar_symbol } =
-                    self.reader.read_plugin_metadata(vi);
+        let load_macros = match macro_selection.as_ref() {
+            Some(sel) => sel.len() != 0 || reexport.len() != 0,
+            None => true,
+        };
+        let load_registrar = plugin_attr.is_some();
 
-                self.plugins.macros.push(ExportedMacros {
-                    crate_name: name,
-                    macros: macros,
-                });
+        if load_macros && !self.span_whitelist.contains(&vi.span) {
+            self.sess.span_err(vi.span, "an `extern crate` loading macros must be at \
+                                         the crate root");
+        }
 
-                match (lib, registrar_symbol) {
-                    (Some(lib), Some(symbol))
-                        => self.dylink_registrar(vi, lib, symbol),
-                    _ => (),
-                }
+        if load_macros || load_registrar {
+            let pmd = self.reader.read_plugin_metadata(vi);
+            if load_macros {
+                macros = pmd.exported_macros();
+            }
+            if load_registrar {
+                registrar = pmd.plugin_registrar();
             }
-            _ => (),
+        }
+
+        for mut def in macros.into_iter() {
+            let name = token::get_ident(def.ident);
+            def.use_locally = match macro_selection.as_ref() {
+                None => true,
+                Some(sel) => sel.contains(&name),
+            };
+            def.export = reexport.contains(&name);
+            self.plugins.macros.push(def);
+        }
+
+        if let Some((lib, symbol)) = registrar {
+            let fun = self.dylink_registrar(vi, lib, symbol);
+            self.plugins.registrars.push(PluginRegistrar {
+                fun: fun,
+                args: plugin_attr.unwrap(),
+            });
         }
     }
+
     fn visit_mac(&mut self, _: &ast::Mac) {
         // bummer... can't see plugins inside macros.
         // do nothing.
@@ -132,7 +211,10 @@ fn visit_mac(&mut self, _: &ast::Mac) {
 
 impl<'a> PluginLoader<'a> {
     // Dynamically link a registrar function into the compiler process.
-    fn dylink_registrar(&mut self, vi: &ast::ViewItem, path: Path, symbol: String) {
+    fn dylink_registrar(&mut self,
+                        vi: &ast::ViewItem,
+                        path: Path,
+                        symbol: String) -> PluginRegistrarFun {
         // Make sure the path contains a / or the linker will search for it.
         let path = os::make_absolute(&path).unwrap();
 
@@ -154,13 +236,12 @@ fn dylink_registrar(&mut self, vi: &ast::ViewItem, path: Path, symbol: String) {
                     Err(err) => self.sess.span_fatal(vi.span, err[])
                 };
 
-            self.plugins.registrars.push(registrar);
-
             // Intentionally leak the dynamic library. We can't ever unload it
             // since the library can make things that will live arbitrarily long
             // (e.g. an @-box cycle or a task).
             mem::forget(lib);
 
+            registrar
         }
     }
 }
index 8dd60880cdd56022773879ed502dcce3bc4ed8f7..fd8873454b4d983fe21831454c17fe083744075e 100644 (file)
 //! To use a plugin while compiling another crate:
 //!
 //! ```rust
-//! #![feature(phase)]
+//! #![feature(plugin)]
 //!
-//! #[phase(plugin)]
+//! #[plugin]
 //! extern crate myplugin;
 //! ```
 //!
-//! If you also need the plugin crate available at runtime, use
-//! `phase(plugin, link)`.
+//! If you don't need the plugin crate available at runtime, use
+//! `#[no_link]` as well.
 //!
 //! See [the compiler plugin guide](../../guide-plugin.html)
 //! for more examples.
index 99e870a901e0893240a9acb87a6ccf4559d041f4..feec97f02da55dd204399f7bdf39066605298934 100644 (file)
 //! Used by plugin crates to tell `rustc` about the plugins they provide.
 
 use lint::{LintPassObject, LintId, Lint};
+use session::Session;
 
 use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
-use syntax::ext::base::{IdentTT, LetSyntaxTT, Decorator, Modifier};
+use syntax::ext::base::{IdentTT, Decorator, Modifier, MacroRulesTT};
 use syntax::ext::base::{MacroExpanderFn};
 use syntax::codemap::Span;
 use syntax::parse::token;
+use syntax::ptr::P;
 use syntax::ast;
 
 use std::collections::HashMap;
 /// This struct has public fields and other methods for use by `rustc`
 /// itself. They are not documented here, and plugin authors should
 /// not use them.
-pub struct Registry {
+pub struct Registry<'a> {
+    /// Compiler session. Useful if you want to emit diagnostic messages
+    /// from the plugin registrar.
+    pub sess: &'a Session,
+
+    #[doc(hidden)]
+    pub args_hidden: Option<P<ast::MetaItem>>,
+
     #[doc(hidden)]
     pub krate_span: Span,
 
@@ -43,10 +52,12 @@ pub struct Registry {
     pub lint_groups: HashMap<&'static str, Vec<LintId>>,
 }
 
-impl Registry {
+impl<'a> Registry<'a> {
     #[doc(hidden)]
-    pub fn new(krate: &ast::Crate) -> Registry {
+    pub fn new(sess: &'a Session, krate: &ast::Crate) -> Registry<'a> {
         Registry {
+            sess: sess,
+            args_hidden: None,
             krate_span: krate.span,
             syntax_exts: vec!(),
             lint_passes: vec!(),
@@ -54,6 +65,14 @@ pub fn new(krate: &ast::Crate) -> Registry {
         }
     }
 
+    /// Get the `#[plugin]` attribute used to load this plugin.
+    ///
+    /// This gives access to arguments passed via `#[plugin=...]` or
+    /// `#[plugin(...)]`.
+    pub fn args<'b>(&'b self) -> &'b P<ast::MetaItem> {
+        self.args_hidden.as_ref().expect("args not set")
+    }
+
     /// Register a syntax extension of any kind.
     ///
     /// This is the most general hook into `libsyntax`'s expansion behavior.
@@ -63,8 +82,11 @@ pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxEx
             IdentTT(ext, _) => IdentTT(ext, Some(self.krate_span)),
             Decorator(ext) => Decorator(ext),
             Modifier(ext) => Modifier(ext),
-            // there's probably a nicer way to signal this:
-            LetSyntaxTT(_, _) => panic!("can't register a new LetSyntax!"),
+
+            MacroRulesTT => {
+                self.sess.err("plugin tried to register a new MacroRulesTT");
+                return;
+            }
         }));
     }
 
index 2bb99a7141f7098c8d74ad9375eb66ad193ce83e..238c84e88a9e0178fb37d9e17ffca8fd71535ee5 100644 (file)
 #![feature(unboxed_closures)]
 #![feature(old_orphan_check)]
 
+#[cfg(stage0)]
 #[phase(plugin, link)]
 extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
 extern crate syntax;
 extern crate serialize;
 
index 1e55f442fb9ac97df9d16266671836d80a75c15e..d606c5158d0f7d930ae003664e2ac4cee9f47f59 100644 (file)
@@ -346,12 +346,12 @@ fn sigma1(x: u32) -> u32 {
 
         // Sha-512 and Sha-256 use basically the same calculations which are implemented
         // by these macros. Inlining the calculations seems to result in better generated code.
-        macro_rules! schedule_round( ($t:expr) => (
+        macro_rules! schedule_round { ($t:expr) => (
                 w[$t] = sigma1(w[$t - 2]) + w[$t - 7] + sigma0(w[$t - 15]) + w[$t - 16];
                 )
-        );
+        }
 
-        macro_rules! sha2_round(
+        macro_rules! sha2_round {
             ($A:ident, $B:ident, $C:ident, $D:ident,
              $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
                 {
@@ -360,7 +360,7 @@ macro_rules! sha2_round(
                     $H += sum0($A) + maj($A, $B, $C);
                 }
              )
-        );
+        }
 
         read_u32v_be(w.slice_mut(0, 16), data);
 
index 2ae88aa4476f7e24f8db8ddb0cf294fc9554ed4f..86bd74d3f85e5b2ca97769ca579130767638a09a 100644 (file)
@@ -327,11 +327,11 @@ fn content<K:InternKey>(k: K) -> token::InternedString { k.get_content() }
 
     impl<'a, 'v> Visitor<'v> for StrictVersionHashVisitor<'a> {
 
-        fn visit_mac(&mut self, macro: &Mac) {
+        fn visit_mac(&mut self, mac: &Mac) {
             // macro invocations, namely macro_rules definitions,
             // *can* appear as items, even in the expanded crate AST.
 
-            if macro_name(macro).get() == "macro_rules" {
+            if macro_name(mac).get() == "macro_rules" {
                 // Pretty-printing definition to a string strips out
                 // surface artifacts (currently), such as the span
                 // information, yielding a content-based hash.
@@ -341,7 +341,7 @@ fn visit_mac(&mut self, macro: &Mac) {
                 // trees might be faster. Implementing this is far
                 // easier in short term.
                 let macro_defn_as_string = pprust::to_string(|pp_state| {
-                    pp_state.print_mac(macro, token::Paren)
+                    pp_state.print_mac(mac, token::Paren)
                 });
                 macro_defn_as_string.hash(self.st);
             } else {
@@ -349,14 +349,14 @@ fn visit_mac(&mut self, macro: &Mac) {
                 // invocation at this stage except `macro_rules!`.
                 panic!("reached macro somehow: {}",
                       pprust::to_string(|pp_state| {
-                          pp_state.print_mac(macro, token::Paren)
+                          pp_state.print_mac(mac, token::Paren)
                       }));
             }
 
-            visit::walk_mac(self, macro);
+            visit::walk_mac(self, mac);
 
-            fn macro_name(macro: &Mac) -> token::InternedString {
-                match &macro.node {
+            fn macro_name(mac: &Mac) -> token::InternedString {
+                match &mac.node {
                     &MacInvocTT(ref path, ref _tts, ref _stx_ctxt) => {
                         let s = path.segments[];
                         assert_eq!(s.len(), 1);
index d53f97c3a04233c3949561d88ca38784f7645dae..f14583bb9aa81b23282861f47019b9786790d6ce 100644 (file)
@@ -239,7 +239,7 @@ pub fn from_json(obj: Json) -> Target {
             options: Default::default(),
         };
 
-        macro_rules! key (
+        macro_rules! key {
             ($key_name:ident) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.find(name[]).map(|o| o.as_string()
@@ -257,7 +257,7 @@ macro_rules! key (
                         )
                     );
             } );
-        );
+        }
 
         key!(cpu);
         key!(linker);
@@ -305,7 +305,7 @@ fn load_file(path: &Path) -> Result<Target, String> {
         }
 
         // this would use a match if stringify! were allowed in pattern position
-        macro_rules! load_specific (
+        macro_rules! load_specific {
             ( $($name:ident),+ ) => (
                 {
                     let target = target.replace("-", "_");
@@ -326,7 +326,7 @@ macro_rules! load_specific (
                     }
                 }
             )
-        );
+        }
 
         load_specific!(
             x86_64_unknown_linux_gnu,
index e1f0c9ec26677abef3eb817672c78b396bfc8686..20949151557cbeec572e1cd76102e75ec5d2c399 100644 (file)
 use syntax::visit::{Visitor, FnKind};
 use syntax::ast::{FnDecl, Block, NodeId};
 
-macro_rules! if_ok {
-    ($inp: expr) => (
-        match $inp {
-            Ok(v) => { v }
-            Err(e) => { return Err(e); }
-        }
-    )
-}
-
 pub mod doc;
 
 pub mod check_loans;
index b886883c73ad21c989cf14d10f0d6e9e8c401f35..0600ddba01897e1e257848c6533ca51b90c9c67a 100644 (file)
 #![feature(old_orphan_check)]
 #![allow(non_camel_case_types)]
 
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
 
 // for "clarity", rename the graphviz crate to dot; graphviz within `borrowck`
 // refers to the borrowck-specific graphviz adapter traits.
index b029b4757c1404aa9596fbc5d47ce26e19701f84..74f81ae9d6d1eeb7f256f4cc940e847caa7a574d 100644 (file)
@@ -12,7 +12,7 @@
 use rustc::session::config::{self, Input, OutputFilenames};
 use rustc::session::search_paths::PathKind;
 use rustc::lint;
-use rustc::metadata::creader;
+use rustc::metadata::creader::CrateReader;
 use rustc::middle::{stability, ty, reachable};
 use rustc::middle::dependency_format;
 use rustc::middle;
@@ -182,7 +182,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
     // strip before expansion to allow macros to depend on
     // configuration variables e.g/ in
     //
-    //   #[macro_escape] #[cfg(foo)]
+    //   #[macro_use] #[cfg(foo)]
     //   mod bar { macro_rules! baz!(() => {{}}) }
     //
     // baz! should not use this definition unless foo is enabled.
@@ -216,9 +216,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
         = time(time_passes, "plugin loading", (), |_|
                plugin::load::load_plugins(sess, &krate, addl_plugins.take().unwrap()));
 
-    let mut registry = Registry::new(&krate);
+    let mut registry = Registry::new(sess, &krate);
 
-    time(time_passes, "plugin registration", (), |_| {
+    time(time_passes, "plugin registration", registrars, |registrars| {
         if sess.features.borrow().rustc_diagnostic_macros {
             registry.register_macro("__diagnostic_used",
                 diagnostics::plugin::expand_diagnostic_used);
@@ -228,8 +228,9 @@ pub fn phase_2_configure_and_expand(sess: &Session,
                 diagnostics::plugin::expand_build_diagnostic_array);
         }
 
-        for &registrar in registrars.iter() {
-            registrar(&mut registry);
+        for registrar in registrars.into_iter() {
+            registry.args_hidden = Some(registrar.args);
+            (registrar.fun)(&mut registry);
         }
     });
 
@@ -351,7 +352,7 @@ pub fn phase_3_run_analysis_passes<'tcx>(sess: Session,
     let krate = ast_map.krate();
 
     time(time_passes, "external crate/lib resolution", (), |_|
-         creader::read_crates(&sess, krate));
+         CrateReader::new(&sess).read_crates(krate));
 
     let lang_items = time(time_passes, "language item collection", (), |_|
                           middle::lang_items::collect_language_items(krate, &sess));
index 2e8cde658904cc3304c08207c88871537cf98e0d..89b2e0f257acd97b5ca75a1b0c2b393e0f7e84dc 100644 (file)
 extern crate rustc_resolve;
 extern crate rustc_trans;
 extern crate rustc_typeck;
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
 extern crate serialize;
 extern crate "rustc_llvm" as llvm;
 
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
+
 pub use syntax::diagnostic;
 
 use rustc_trans::back::link;
index d972229e7c75b25f08e3cbf9aadd73b66357f64c..61fd7d16ab7ddea401a618297fa3dc6e7cafc56d 100644 (file)
@@ -484,8 +484,8 @@ fn expr_to_block(rules: ast::BlockCheckMode,
 
     // in general the pretty printer processes unexpanded code, so
     // we override the default `fold_mac` method which panics.
-    fn fold_mac(&mut self, _macro: ast::Mac) -> ast::Mac {
-        fold::noop_fold_mac(_macro, self)
+    fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+        fold::noop_fold_mac(mac, self)
     }
 }
 
index adbcf8c2e8e4bd2ec8d939863bb1c26a2b608ab9..58102fe5629d9f43bc2656d609830f2451a0f68e 100644 (file)
 #![feature(associated_types)]
 #![feature(old_orphan_check)]
 
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
 
 extern crate rustc;
 
index 9dbff66aba2864518a24e484751ef50e796a68f9..705fecf4d198eec8b7590c53b659c719dbf93fdf 100644 (file)
 extern crate libc;
 extern crate rustc;
 extern crate rustc_back;
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
 extern crate serialize;
 extern crate "rustc_llvm" as llvm;
 
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
+
 pub use rustc::session;
 pub use rustc::metadata;
 pub use rustc::middle;
index f974a6faf4c19d8e6feb31b7e4cda3417e86a312..3726cf14023ee35c88ac7b05af5cbe377ff75b87 100644 (file)
@@ -736,7 +736,7 @@ pub fn report_overbig_object(&self, obj: Ty<'tcx>) -> ! {
 }
 
 fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef> {
-    macro_rules! ifn (
+    macro_rules! ifn {
         ($name:expr fn() -> $ret:expr) => (
             if *key == $name {
                 let f = base::decl_cdecl_fn(
@@ -754,10 +754,10 @@ macro_rules! ifn (
                 return Some(f);
             }
         )
-    );
-    macro_rules! mk_struct (
+    }
+    macro_rules! mk_struct {
         ($($field_ty:expr),*) => (Type::struct_(ccx, &[$($field_ty),*], false))
-    );
+    }
 
     let i8p = Type::i8p(ccx);
     let void = Type::void(ccx);
@@ -878,7 +878,7 @@ macro_rules! mk_struct (
     // Some intrinsics were introduced in later versions of LLVM, but they have
     // fallbacks in libc or libm and such. Currently, all of these intrinsics
     // were introduced in LLVM 3.4, so we case on that.
-    macro_rules! compatible_ifn (
+    macro_rules! compatible_ifn {
         ($name:expr, $cname:ident ($($arg:expr),*) -> $ret:expr) => (
             if unsafe { llvm::LLVMVersionMinor() >= 4 } {
                 // The `if key == $name` is already in ifn!
@@ -891,7 +891,7 @@ macro_rules! compatible_ifn (
                 return Some(f);
             }
         )
-    );
+    }
 
     compatible_ifn!("llvm.copysign.f32", copysignf(t_f32, t_f32) -> t_f32);
     compatible_ifn!("llvm.copysign.f64", copysign(t_f64, t_f64) -> t_f64);
index ab202975bfc152d8b9b424dffbfd51541d85a7db..77efcc6fb0030d9d768d644c02f30696ec91b09b 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
 macro_rules! unpack_datum {
     ($bcx: ident, $inp: expr) => (
         {
index 72c4def15a215d69018908b3d5e23f785568b7fb..fa9cd5a698bbe05784d661832f89cbb630529f90 100644 (file)
 pub use self::context::CrateContext;
 pub use self::common::gensym_name;
 
-mod doc;
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 mod macros;
+
+mod doc;
 mod inline;
 mod monomorphize;
 mod controlflow;
index 3146a1181396b439ca00885e59d85d340940d110..dc434f1401585af1fa782235e983011bb418430e 100644 (file)
 #![feature(unboxed_closures)]
 #![allow(non_camel_case_types)]
 
-#[phase(plugin, link)] extern crate log;
-#[phase(plugin, link)] extern crate syntax;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate syntax;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate syntax;
 
 extern crate arena;
 extern crate rustc;
index cfaae1a9f80fd13b0f511fb69c6571d1441adadc..30b9d6c63c5bb127db68bb38141011e850ed0f3c 100644 (file)
@@ -166,6 +166,9 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
                 }
             }
 
+            // Special macro vars are like keywords
+            token::SpecialVarNt(_) => "kw-2",
+
             token::Lifetime(..) => "lifetime",
             token::DocComment(..) => "doccomment",
             token::Underscore | token::Eof | token::Interpolated(..) |
index 106fe452f46a6059a931a1973681f516f3454096..6e42c50f974c51f2a4748db95d47c78a2ddf9fbe 100644 (file)
 extern crate serialize;
 extern crate syntax;
 extern crate "test" as testing;
-#[phase(plugin, link)] extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
 
 extern crate "serialize" as rustc_serialize; // used by deriving
 
 // reexported from `clean` so it can be easily updated with the mod itself
 pub use clean::SCHEMA_VERSION;
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+pub mod externalfiles;
+
 pub mod clean;
 pub mod core;
 pub mod doctree;
-#[macro_escape]
-pub mod externalfiles;
 pub mod fold;
 pub mod html {
     pub mod highlight;
index c98ec97ab87f0b806eb83c297b8428f78e186835..ad67672ea6ea741a35dc916fe31c990ee0f183f2 100644 (file)
@@ -73,7 +73,7 @@ pub fn visit(&mut self, krate: &ast::Crate) {
                                               None);
         // attach the crate's exported macros to the top-level module:
         self.module.macros = krate.exported_macros.iter()
-            .map(|it| self.visit_macro(&**it)).collect();
+            .map(|def| self.visit_macro(def)).collect();
         self.module.is_crate = true;
     }
 
@@ -363,13 +363,13 @@ pub fn visit_item(&mut self, item: &ast::Item,
     }
 
     // convert each exported_macro into a doc item
-    fn visit_macro(&self, item: &ast::Item) -> Macro {
+    fn visit_macro(&self, def: &ast::MacroDef) -> Macro {
         Macro {
-            id: item.id,
-            attrs: item.attrs.clone(),
-            name: item.ident,
-            whence: item.span,
-            stab: self.stability(item.id),
+            id: def.id,
+            attrs: def.attrs.clone(),
+            name: def.ident,
+            whence: def.span,
+            stab: self.stability(def.id),
         }
     }
 }
index 8ad2013f9368f256fe50f734ce8a59eaff30502c..8fe15f00ded73e55f60285fd6720e192686b49fb 100644 (file)
 #[cfg(test)]
 extern crate test;
 
+#[cfg(stage0)]
 #[phase(plugin, link)]
 extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
 extern crate unicode;
 
 extern crate collections;
index 65cbce08543cc3c84e118f0a4b2fb7ecec1917c6..ed3f2cbe1a1da3f5471e06bb12aa2d0de1f0309d 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![experimental]
-#![macro_escape]
 
 //! A typesafe bitmask flag generator.
 
index 91a5db2ba763157349beb7a50b9c33c0e52a72d0..38ea4dad027a09b0a6d41b6a816501d16b773920 100644 (file)
@@ -21,7 +21,9 @@
 use iter::{Iterator, IteratorExt, FromIterator, Map, Chain, Extend};
 use ops::{BitOr, BitAnd, BitXor, Sub};
 use option::Option::{Some, None, self};
-use result::Result::{Ok, Err};
+
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::{Ok, Err};
 
 use super::map::{self, HashMap, Keys, INITIAL_CAPACITY};
 
index c4e37264e2aeeb2d3ff1a83d58be901a2cc8e24a..d590aa8419453d6de9ce3ed35c62fba98b719052 100644 (file)
 use ops::Drop;
 use option::Option;
 use option::Option::{Some, None};
-use result::Result::{Ok, Err};
+use result::Result::Ok;
 use slice::{SliceExt};
 use slice;
 use vec::Vec;
 
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::Err;
+
 /// Wraps a Reader and buffers input from it
 ///
 /// It can be excessively inefficient to work directly with a `Reader`. For
index 66416a21dd9a449e87fe9f5de7ffa31a5922ec3e..5bef473db990c8879a7fcb23d801ad6a88321769 100644 (file)
 pub mod pipe;
 pub mod process;
 pub mod stdio;
-pub mod test;
 pub mod timer;
 pub mod util;
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+pub mod test;
+
 /// The default buffer size for various I/O operations
 // libuv recommends 64k buffers to maximize throughput
 // https://groups.google.com/forum/#!topic/libuv/oQO1HJAIDdA
index 3ce56c907b33d0dc2eceb49ca917fefcbeaa0cb7..6eeef175f73d50844c1d17123385c3cc544a61da 100644 (file)
@@ -10,8 +10,6 @@
 
 //! Various utility functions useful for writing I/O tests
 
-#![macro_escape]
-
 use prelude::v1::*;
 
 use libc;
index a1c529186371deec5747a7402f371431b9281c88..e937cd24d8d78274f128f9f6c95528128347ba46 100644 (file)
 
 #![reexport_test_harness_main = "test_main"]
 
-#[cfg(test)] #[phase(plugin, link)] extern crate log;
+#[cfg(all(test, stage0))]
+#[phase(plugin, link)]
+extern crate log;
 
-extern crate alloc;
-extern crate unicode;
+#[cfg(all(test, not(stage0)))]
+#[macro_use]
+extern crate log;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate core;
+
+#[cfg(not(stage0))]
+#[macro_use]
+#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
+    unreachable, unimplemented, write, writeln)]
 extern crate core;
+
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate "collections" as core_collections;
+
+#[cfg(not(stage0))]
+#[macro_use]
+#[macro_reexport(vec)]
 extern crate "collections" as core_collections;
+
 extern crate "rand" as core_rand;
+extern crate alloc;
+extern crate unicode;
 extern crate libc;
 
 // Make std testable by not duplicating lang items. See #2912
 
 /* Exported macros */
 
+#[cfg(stage0)]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+pub mod macros_stage0;
+
+#[cfg(not(stage0))]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 pub mod macros;
+
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 pub mod bitflags;
 
 mod rtdeps;
 
 /* Primitive types */
 
-#[path = "num/float_macros.rs"] mod float_macros;
-#[path = "num/int_macros.rs"]   mod int_macros;
-#[path = "num/uint_macros.rs"]  mod uint_macros;
+#[path = "num/float_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod float_macros;
+
+#[path = "num/int_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod int_macros;
+
+#[path = "num/uint_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod uint_macros;
 
 #[path = "num/int.rs"]  pub mod int;
 #[path = "num/i8.rs"]   pub mod i8;
 
 pub mod thread_local; // first for macros
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+pub mod thread_local;
+
 pub mod dynamic_lib;
 pub mod ffi;
 pub mod fmt;
index fb2d23b01b4644c990baaa0d4fa6e481bc198586..22cbf16e2b0b98d80483556d894b8a3e6df7236f 100644 (file)
@@ -15,7 +15,6 @@
 //! library.
 
 #![experimental]
-#![macro_escape]
 
 /// The entry point for panic of Rust tasks.
 ///
@@ -246,34 +245,6 @@ macro_rules! format {
     ($($arg:tt)*) => (::std::fmt::format(format_args!($($arg)*)))
 }
 
-/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
-/// See `std::fmt` for more information.
-///
-/// # Example
-///
-/// ```
-/// # #![allow(unused_must_use)]
-///
-/// let mut w = Vec::new();
-/// write!(&mut w, "test");
-/// write!(&mut w, "formatted {}", "arguments");
-/// ```
-#[macro_export]
-#[stable]
-macro_rules! write {
-    ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
-}
-
-/// Equivalent to the `write!` macro, except that a newline is appended after
-/// the message is written.
-#[macro_export]
-#[stable]
-macro_rules! writeln {
-    ($dst:expr, $fmt:expr $($arg:tt)*) => (
-        write!($dst, concat!($fmt, "\n") $($arg)*)
-    )
-}
-
 /// Equivalent to the `println!` macro except that a newline is not printed at
 /// the end of the message.
 #[macro_export]
@@ -306,23 +277,15 @@ macro_rules! println {
 #[macro_export]
 macro_rules! try {
     ($expr:expr) => ({
+        use $crate::result::Result::{Ok, Err};
+
         match $expr {
             Ok(val) => val,
-            Err(err) => return Err(::std::error::FromError::from_error(err))
+            Err(err) => return Err($crate::error::FromError::from_error(err)),
         }
     })
 }
 
-/// Create a `std::vec::Vec` containing the arguments.
-#[macro_export]
-macro_rules! vec {
-    ($($x:expr),*) => ({
-        let xs: ::std::boxed::Box<[_]> = box [$($x),*];
-        ::std::slice::SliceExt::into_vec(xs)
-    });
-    ($($x:expr,)*) => (vec![$($x),*])
-}
-
 /// A macro to select an event from a number of receivers.
 ///
 /// This macro is used to wait for the first event to occur on a number of
@@ -358,7 +321,7 @@ macro_rules! select {
     (
         $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
     ) => ({
-        use std::sync::mpsc::Select;
+        use $crate::sync::mpsc::Select;
         let sel = Select::new();
         $( let mut $rx = sel.handle(&$rx); )+
         unsafe {
diff --git a/src/libstd/macros_stage0.rs b/src/libstd/macros_stage0.rs
new file mode 100644 (file)
index 0000000..48d62e7
--- /dev/null
@@ -0,0 +1,648 @@
+// Copyright 2014 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.
+
+//! Standard library macros
+//!
+//! This modules contains a set of macros which are exported from the standard
+//! library. Each macro is available for use when linking against the standard
+//! library.
+
+#![experimental]
+
+/// The entry point for panic of Rust tasks.
+///
+/// This macro is used to inject panic into a Rust task, causing the task to
+/// unwind and panic entirely. Each task's panic can be reaped as the
+/// `Box<Any>` type, and the single-argument form of the `panic!` macro will be
+/// the value which is transmitted.
+///
+/// The multi-argument form of this macro panics with a string and has the
+/// `format!` syntax for building a string.
+///
+/// # Example
+///
+/// ```should_fail
+/// # #![allow(unreachable_code)]
+/// panic!();
+/// panic!("this is a terrible mistake!");
+/// panic!(4i); // panic with the value of 4 to be collected elsewhere
+/// panic!("this is a {} {message}", "fancy", message = "message");
+/// ```
+#[macro_export]
+macro_rules! panic {
+    () => ({
+        panic!("explicit panic")
+    });
+    ($msg:expr) => ({
+        // static requires less code at runtime, more constant data
+        static _FILE_LINE: (&'static str, uint) = (file!(), line!());
+        ::std::rt::begin_unwind($msg, &_FILE_LINE)
+    });
+    ($fmt:expr, $($arg:tt)*) => ({
+        // The leading _'s are to avoid dead code warnings if this is
+        // used inside a dead function. Just `#[allow(dead_code)]` is
+        // insufficient, since the user may have
+        // `#[forbid(dead_code)]` and which cannot be overridden.
+        static _FILE_LINE: (&'static str, uint) = (file!(), line!());
+        ::std::rt::begin_unwind_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
+
+    });
+}
+
+/// Ensure that a boolean expression is `true` at runtime.
+///
+/// This will invoke the `panic!` macro if the provided expression cannot be
+/// evaluated to `true` at runtime.
+///
+/// # Example
+///
+/// ```
+/// // the panic message for these assertions is the stringified value of the
+/// // expression given.
+/// assert!(true);
+/// # fn some_computation() -> bool { true }
+/// assert!(some_computation());
+///
+/// // assert with a custom message
+/// # let x = true;
+/// assert!(x, "x wasn't true!");
+/// # let a = 3i; let b = 27i;
+/// assert!(a + b == 30, "a = {}, b = {}", a, b);
+/// ```
+#[macro_export]
+macro_rules! assert {
+    ($cond:expr) => (
+        if !$cond {
+            panic!(concat!("assertion failed: ", stringify!($cond)))
+        }
+    );
+    ($cond:expr, $($arg:expr),+) => (
+        if !$cond {
+            panic!($($arg),+)
+        }
+    );
+}
+
+/// Asserts that two expressions are equal to each other, testing equality in
+/// both directions.
+///
+/// On panic, this macro will print the values of the expressions.
+///
+/// # Example
+///
+/// ```
+/// let a = 3i;
+/// let b = 1i + 2i;
+/// assert_eq!(a, b);
+/// ```
+#[macro_export]
+macro_rules! assert_eq {
+    ($left:expr , $right:expr) => ({
+        match (&($left), &($right)) {
+            (left_val, right_val) => {
+                // check both directions of equality....
+                if !((*left_val == *right_val) &&
+                     (*right_val == *left_val)) {
+                    panic!("assertion failed: `(left == right) && (right == left)` \
+                           (left: `{}`, right: `{}`)", *left_val, *right_val)
+                }
+            }
+        }
+    })
+}
+
+/// Ensure that a boolean expression is `true` at runtime.
+///
+/// This will invoke the `panic!` macro if the provided expression cannot be
+/// evaluated to `true` at runtime.
+///
+/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
+/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
+/// checks that are too expensive to be present in a release build but may be
+/// helpful during development.
+///
+/// # Example
+///
+/// ```
+/// // the panic message for these assertions is the stringified value of the
+/// // expression given.
+/// debug_assert!(true);
+/// # fn some_expensive_computation() -> bool { true }
+/// debug_assert!(some_expensive_computation());
+///
+/// // assert with a custom message
+/// # let x = true;
+/// debug_assert!(x, "x wasn't true!");
+/// # let a = 3i; let b = 27i;
+/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
+/// ```
+#[macro_export]
+macro_rules! debug_assert {
+    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+}
+
+/// Asserts that two expressions are equal to each other, testing equality in
+/// both directions.
+///
+/// On panic, this macro will print the values of the expressions.
+///
+/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
+/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
+/// useful for checks that are too expensive to be present in a release build
+/// but may be helpful during development.
+///
+/// # Example
+///
+/// ```
+/// let a = 3i;
+/// let b = 1i + 2i;
+/// debug_assert_eq!(a, b);
+/// ```
+#[macro_export]
+macro_rules! debug_assert_eq {
+    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
+}
+
+/// A utility macro for indicating unreachable code.
+///
+/// This is useful any time that the compiler can't determine that some code is unreachable. For
+/// example:
+///
+/// * Match arms with guard conditions.
+/// * Loops that dynamically terminate.
+/// * Iterators that dynamically terminate.
+///
+/// # Panics
+///
+/// This will always panic.
+///
+/// # Examples
+///
+/// Match arms:
+///
+/// ```rust
+/// fn foo(x: Option<int>) {
+///     match x {
+///         Some(n) if n >= 0 => println!("Some(Non-negative)"),
+///         Some(n) if n <  0 => println!("Some(Negative)"),
+///         Some(_)           => unreachable!(), // compile error if commented out
+///         None              => println!("None")
+///     }
+/// }
+/// ```
+///
+/// Iterators:
+///
+/// ```rust
+/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
+///     for i in std::iter::count(0_u32, 1) {
+///         if 3*i < i { panic!("u32 overflow"); }
+///         if x < 3*i { return i-1; }
+///     }
+///     unreachable!();
+/// }
+/// ```
+#[macro_export]
+macro_rules! unreachable {
+    () => ({
+        panic!("internal error: entered unreachable code")
+    });
+    ($msg:expr) => ({
+        unreachable!("{}", $msg)
+    });
+    ($fmt:expr, $($arg:tt)*) => ({
+        panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
+    });
+}
+
+/// A standardised placeholder for marking unfinished code. It panics with the
+/// message `"not yet implemented"` when executed.
+#[macro_export]
+macro_rules! unimplemented {
+    () => (panic!("not yet implemented"))
+}
+
+/// Use the syntax described in `std::fmt` to create a value of type `String`.
+/// See `std::fmt` for more information.
+///
+/// # Example
+///
+/// ```
+/// format!("test");
+/// format!("hello {}", "world!");
+/// format!("x = {}, y = {y}", 10i, y = 30i);
+/// ```
+#[macro_export]
+#[stable]
+macro_rules! format {
+    ($($arg:tt)*) => (::std::fmt::format(format_args!($($arg)*)))
+}
+
+/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
+/// See `std::fmt` for more information.
+///
+/// # Example
+///
+/// ```
+/// # #![allow(unused_must_use)]
+///
+/// let mut w = Vec::new();
+/// write!(&mut w, "test");
+/// write!(&mut w, "formatted {}", "arguments");
+/// ```
+#[macro_export]
+#[stable]
+macro_rules! write {
+    ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
+}
+
+/// Equivalent to the `write!` macro, except that a newline is appended after
+/// the message is written.
+#[macro_export]
+#[stable]
+macro_rules! writeln {
+    ($dst:expr, $fmt:expr $($arg:tt)*) => (
+        write!($dst, concat!($fmt, "\n") $($arg)*)
+    )
+}
+
+/// Equivalent to the `println!` macro except that a newline is not printed at
+/// the end of the message.
+#[macro_export]
+#[stable]
+macro_rules! print {
+    ($($arg:tt)*) => (::std::io::stdio::print_args(format_args!($($arg)*)))
+}
+
+/// Macro for printing to a task's stdout handle.
+///
+/// Each task can override its stdout handle via `std::io::stdio::set_stdout`.
+/// The syntax of this macro is the same as that used for `format!`. For more
+/// information, see `std::fmt` and `std::io::stdio`.
+///
+/// # Example
+///
+/// ```
+/// println!("hello there!");
+/// println!("format {} arguments", "some");
+/// ```
+#[macro_export]
+#[stable]
+macro_rules! println {
+    ($($arg:tt)*) => (::std::io::stdio::println_args(format_args!($($arg)*)))
+}
+
+/// Helper macro for unwrapping `Result` values while returning early with an
+/// error if the value of the expression is `Err`. For more information, see
+/// `std::io`.
+#[macro_export]
+macro_rules! try {
+    ($expr:expr) => ({
+        match $expr {
+            Ok(val) => val,
+            Err(err) => return Err(::std::error::FromError::from_error(err))
+        }
+    })
+}
+
+/// Create a `std::vec::Vec` containing the arguments.
+#[macro_export]
+macro_rules! vec {
+    ($($x:expr),*) => ({
+        let xs: ::std::boxed::Box<[_]> = box [$($x),*];
+        ::std::slice::SliceExt::into_vec(xs)
+    });
+    ($($x:expr,)*) => (vec![$($x),*])
+}
+
+/// A macro to select an event from a number of receivers.
+///
+/// This macro is used to wait for the first event to occur on a number of
+/// receivers. It places no restrictions on the types of receivers given to
+/// this macro, this can be viewed as a heterogeneous select.
+///
+/// # Example
+///
+/// ```
+/// use std::thread::Thread;
+/// use std::sync::mpsc::channel;
+///
+/// let (tx1, rx1) = channel();
+/// let (tx2, rx2) = channel();
+/// # fn long_running_task() {}
+/// # fn calculate_the_answer() -> int { 42i }
+///
+/// Thread::spawn(move|| { long_running_task(); tx1.send(()) }).detach();
+/// Thread::spawn(move|| { tx2.send(calculate_the_answer()) }).detach();
+///
+/// select! (
+///     _ = rx1.recv() => println!("the long running task finished first"),
+///     answer = rx2.recv() => {
+///         println!("the answer was: {}", answer.unwrap());
+///     }
+/// )
+/// ```
+///
+/// For more information about select, see the `std::sync::mpsc::Select` structure.
+#[macro_export]
+#[experimental]
+macro_rules! select {
+    (
+        $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
+    ) => ({
+        use std::sync::mpsc::Select;
+        let sel = Select::new();
+        $( let mut $rx = sel.handle(&$rx); )+
+        unsafe {
+            $( $rx.add(); )+
+        }
+        let ret = sel.wait();
+        $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
+        { unreachable!() }
+    })
+}
+
+// When testing the standard library, we link to the liblog crate to get the
+// logging macros. In doing so, the liblog crate was linked against the real
+// version of libstd, and uses a different std::fmt module than the test crate
+// uses. To get around this difference, we redefine the log!() macro here to be
+// just a dumb version of what it should be.
+#[cfg(test)]
+macro_rules! log {
+    ($lvl:expr, $($args:tt)*) => (
+        if log_enabled!($lvl) { println!($($args)*) }
+    )
+}
+
+/// Built-in macros to the compiler itself.
+///
+/// These macros do not have any corresponding definition with a `macro_rules!`
+/// macro, but are documented here. Their implementations can be found hardcoded
+/// into libsyntax itself.
+#[cfg(dox)]
+pub mod builtin {
+    /// The core macro for formatted string creation & output.
+    ///
+    /// This macro produces a value of type `fmt::Arguments`. This value can be
+    /// passed to the functions in `std::fmt` for performing useful functions.
+    /// All other formatting macros (`format!`, `write!`, `println!`, etc) are
+    /// proxied through this one.
+    ///
+    /// For more information, see the documentation in `std::fmt`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::fmt;
+    ///
+    /// let s = fmt::format(format_args!("hello {}", "world"));
+    /// assert_eq!(s, format!("hello {}", "world"));
+    ///
+    /// ```
+    #[macro_export]
+    macro_rules! format_args { ($fmt:expr $($args:tt)*) => ({
+        /* compiler built-in */
+    }) }
+
+    /// Inspect an environment variable at compile time.
+    ///
+    /// This macro will expand to the value of the named environment variable at
+    /// compile time, yielding an expression of type `&'static str`.
+    ///
+    /// If the environment variable is not defined, then a compilation error
+    /// will be emitted.  To not emit a compile error, use the `option_env!`
+    /// macro instead.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let path: &'static str = env!("PATH");
+    /// println!("the $PATH variable at the time of compiling was: {}", path);
+    /// ```
+    #[macro_export]
+    macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }
+
+    /// Optionally inspect an environment variable at compile time.
+    ///
+    /// If the named environment variable is present at compile time, this will
+    /// expand into an expression of type `Option<&'static str>` whose value is
+    /// `Some` of the value of the environment variable. If the environment
+    /// variable is not present, then this will expand to `None`.
+    ///
+    /// A compile time error is never emitted when using this macro regardless
+    /// of whether the environment variable is present or not.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let key: Option<&'static str> = option_env!("SECRET_KEY");
+    /// println!("the secret key might be: {}", key);
+    /// ```
+    #[macro_export]
+    macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) }
+
+    /// Concatenate literals into a static byte slice.
+    ///
+    /// This macro takes any number of comma-separated literal expressions,
+    /// yielding an expression of type `&'static [u8]` which is the
+    /// concatenation (left to right) of all the literals in their byte format.
+    ///
+    /// This extension currently only supports string literals, character
+    /// literals, and integers less than 256. The byte slice returned is the
+    /// utf8-encoding of strings and characters.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let rust = bytes!("r", 'u', "st", 255);
+    /// assert_eq!(rust[1], b'u');
+    /// assert_eq!(rust[4], 255);
+    /// ```
+    #[macro_export]
+    macro_rules! bytes { ($($e:expr),*) => ({ /* compiler built-in */ }) }
+
+    /// Concatenate identifiers into one identifier.
+    ///
+    /// This macro takes any number of comma-separated identifiers, and
+    /// concatenates them all into one, yielding an expression which is a new
+    /// identifier. Note that hygiene makes it such that this macro cannot
+    /// capture local variables, and macros are only allowed in item,
+    /// statement or expression position, meaning this macro may be difficult to
+    /// use in some situations.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// #![feature(concat_idents)]
+    ///
+    /// # fn main() {
+    /// fn foobar() -> int { 23 }
+    ///
+    /// let f = concat_idents!(foo, bar);
+    /// println!("{}", f());
+    /// # }
+    /// ```
+    #[macro_export]
+    macro_rules! concat_idents {
+        ($($e:ident),*) => ({ /* compiler built-in */ })
+    }
+
+    /// Concatenates literals into a static string slice.
+    ///
+    /// This macro takes any number of comma-separated literals, yielding an
+    /// expression of type `&'static str` which represents all of the literals
+    /// concatenated left-to-right.
+    ///
+    /// Integer and floating point literals are stringified in order to be
+    /// concatenated.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let s = concat!("test", 10i, 'b', true);
+    /// assert_eq!(s, "test10btrue");
+    /// ```
+    #[macro_export]
+    macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }
+
+    /// A macro which expands to the line number on which it was invoked.
+    ///
+    /// The expanded expression has type `uint`, and the returned line is not
+    /// the invocation of the `line!()` macro itself, but rather the first macro
+    /// invocation leading up to the invocation of the `line!()` macro.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let current_line = line!();
+    /// println!("defined on line: {}", current_line);
+    /// ```
+    #[macro_export]
+    macro_rules! line { () => ({ /* compiler built-in */ }) }
+
+    /// A macro which expands to the column number on which it was invoked.
+    ///
+    /// The expanded expression has type `uint`, and the returned column is not
+    /// the invocation of the `column!()` macro itself, but rather the first macro
+    /// invocation leading up to the invocation of the `column!()` macro.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let current_col = column!();
+    /// println!("defined on column: {}", current_col);
+    /// ```
+    #[macro_export]
+    macro_rules! column { () => ({ /* compiler built-in */ }) }
+
+    /// A macro which expands to the file name from which it was invoked.
+    ///
+    /// The expanded expression has type `&'static str`, and the returned file
+    /// is not the invocation of the `file!()` macro itself, but rather the
+    /// first macro invocation leading up to the invocation of the `file!()`
+    /// macro.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let this_file = file!();
+    /// println!("defined in file: {}", this_file);
+    /// ```
+    #[macro_export]
+    macro_rules! file { () => ({ /* compiler built-in */ }) }
+
+    /// A macro which stringifies its argument.
+    ///
+    /// This macro will yield an expression of type `&'static str` which is the
+    /// stringification of all the tokens passed to the macro. No restrictions
+    /// are placed on the syntax of the macro invocation itself.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let one_plus_one = stringify!(1 + 1);
+    /// assert_eq!(one_plus_one, "1 + 1");
+    /// ```
+    #[macro_export]
+    macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }
+
+    /// Includes a utf8-encoded file as a string.
+    ///
+    /// This macro will yield an expression of type `&'static str` which is the
+    /// contents of the filename specified. The file is located relative to the
+    /// current file (similarly to how modules are found),
+    ///
+    /// # Example
+    ///
+    /// ```rust,ignore
+    /// let secret_key = include_str!("secret-key.ascii");
+    /// ```
+    #[macro_export]
+    macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) }
+
+    /// Includes a file as a byte slice.
+    ///
+    /// This macro will yield an expression of type `&'static [u8]` which is
+    /// the contents of the filename specified. The file is located relative to
+    /// the current file (similarly to how modules are found),
+    ///
+    /// # Example
+    ///
+    /// ```rust,ignore
+    /// let secret_key = include_bytes!("secret-key.bin");
+    /// ```
+    #[macro_export]
+    macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) }
+
+    /// Deprecated alias for `include_bytes!()`.
+    #[macro_export]
+    macro_rules! include_bin { ($file:expr) => ({ /* compiler built-in */}) }
+
+    /// Expands to a string that represents the current module path.
+    ///
+    /// The current module path can be thought of as the hierarchy of modules
+    /// leading back up to the crate root. The first component of the path
+    /// returned is the name of the crate currently being compiled.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// mod test {
+    ///     pub fn foo() {
+    ///         assert!(module_path!().ends_with("test"));
+    ///     }
+    /// }
+    ///
+    /// test::foo();
+    /// ```
+    #[macro_export]
+    macro_rules! module_path { () => ({ /* compiler built-in */ }) }
+
+    /// Boolean evaluation of configuration flags.
+    ///
+    /// In addition to the `#[cfg]` attribute, this macro is provided to allow
+    /// boolean expression evaluation of configuration flags. This frequently
+    /// leads to less duplicated code.
+    ///
+    /// The syntax given to this macro is the same syntax as the `cfg`
+    /// attribute.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let my_directory = if cfg!(windows) {
+    ///     "windows-specific-directory"
+    /// } else {
+    ///     "unix-directory"
+    /// };
+    /// ```
+    #[macro_export]
+    macro_rules! cfg { ($cfg:tt) => ({ /* compiler built-in */ }) }
+}
index fd00f15662a72eae099aca9854e2b718597f7cd4..4c52f29b12d763a2433b29af0341b0c29ac1b656 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![experimental]
-#![macro_escape]
 #![doc(hidden)]
 
 macro_rules! assert_approx_eq {
index fce150c4ad1e3676b79509d223c958387e21a486..ebcb20861879c87aebf86b92b17cc568e198ea92 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![experimental]
-#![macro_escape]
 #![doc(hidden)]
 
 macro_rules! int_module { ($T:ty) => (
index 7818f4a053497e22f607bca64dbb5e724d22e74e..08ea1b024c99360264b37d989ac2c099486e1014 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![experimental]
-#![macro_escape]
 #![doc(hidden)]
 #![allow(unsigned_negation)]
 
index 1df02101ed0b0060df3b9f3c3a5f319c0feceb36..d9981ace0301ec52b40ae8453951b392fe99df2d 100644 (file)
@@ -535,7 +535,7 @@ macro_rules! t {
         t!(b"foo/\xFFbar", filename_display, "\u{FFFD}bar");
         t!(b"/", filename_display, "");
 
-        macro_rules! t(
+        macro_rules! t {
             ($path:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -550,7 +550,7 @@ macro_rules! t(
                     assert!(mo.as_slice() == $exp);
                 }
             )
-        );
+        }
 
         t!("foo", "foo");
         t!(b"foo\x80", "foo\u{FFFD}");
@@ -562,7 +562,7 @@ macro_rules! t(
 
     #[test]
     fn test_display() {
-        macro_rules! t(
+        macro_rules! t {
             ($path:expr, $exp:expr, $expf:expr) => (
                 {
                     let path = Path::new($path);
@@ -572,7 +572,7 @@ macro_rules! t(
                     assert!(f == $expf);
                 }
             )
-        );
+        }
 
         t!(b"foo", "foo", "foo");
         t!(b"foo/bar", "foo/bar", "bar");
@@ -585,7 +585,7 @@ macro_rules! t(
 
     #[test]
     fn test_components() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $op:ident, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -606,7 +606,7 @@ macro_rules! t(
                     assert!(path.$op() == $exp);
                 }
             );
-        );
+        }
 
         t!(v: b"a/b/c", filename, Some(b"c"));
         t!(v: b"a/b/c\xFF", filename, Some(b"c\xFF"));
@@ -669,7 +669,7 @@ macro_rules! t(
 
     #[test]
     fn test_push() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $join:expr) => (
                 {
                     let path = $path;
@@ -680,7 +680,7 @@ macro_rules! t(
                     assert!(p1 == p2.join(join));
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", "..");
         t!(s: "/a/b/c", "d");
@@ -690,7 +690,7 @@ macro_rules! t(
 
     #[test]
     fn test_push_path() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $push:expr, $exp:expr) => (
                 {
                     let mut p = Path::new($path);
@@ -699,7 +699,7 @@ macro_rules! t(
                     assert!(p.as_str() == Some($exp));
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", "d", "a/b/c/d");
         t!(s: "/a/b/c", "d", "/a/b/c/d");
@@ -711,7 +711,7 @@ macro_rules! t(
 
     #[test]
     fn test_push_many() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $push:expr, $exp:expr) => (
                 {
                     let mut p = Path::new($path);
@@ -726,7 +726,7 @@ macro_rules! t(
                     assert!(p.as_vec() == $exp);
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", ["d", "e"], "a/b/c/d/e");
         t!(s: "a/b/c", ["d", "/e"], "/e");
@@ -739,7 +739,7 @@ macro_rules! t(
 
     #[test]
     fn test_pop() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $left:expr, $right:expr) => (
                 {
                     let mut p = Path::new($path);
@@ -756,7 +756,7 @@ macro_rules! t(
                     assert!(result == $right);
                 }
             )
-        );
+        }
 
         t!(b: b"a/b/c", b"a/b", true);
         t!(b: b"a", b".", true);
@@ -795,7 +795,7 @@ fn test_join() {
 
     #[test]
     fn test_join_path() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $join:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -804,7 +804,7 @@ macro_rules! t(
                     assert!(res.as_str() == Some($exp));
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", "..", "a/b");
         t!(s: "/a/b/c", "d", "/a/b/c/d");
@@ -816,7 +816,7 @@ macro_rules! t(
 
     #[test]
     fn test_join_many() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $join:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -831,7 +831,7 @@ macro_rules! t(
                     assert!(res.as_vec() == $exp);
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", ["d", "e"], "a/b/c/d/e");
         t!(s: "a/b/c", ["..", "d"], "a/b/d");
@@ -894,7 +894,7 @@ fn test_with_helpers() {
 
     #[test]
     fn test_setters() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $set:ident, $with:ident, $arg:expr) => (
                 {
                     let path = $path;
@@ -915,7 +915,7 @@ macro_rules! t(
                     assert!(p1 == p2.$with(arg));
                 }
             )
-        );
+        }
 
         t!(v: b"a/b/c", set_filename, with_filename, b"d");
         t!(v: b"/", set_filename, with_filename, b"foo");
@@ -938,7 +938,7 @@ macro_rules! t(
 
     #[test]
     fn test_getters() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
                 {
                     let path = $path;
@@ -969,7 +969,7 @@ macro_rules! t(
                     assert!(path.extension() == $ext);
                 }
             )
-        );
+        }
 
         t!(v: Path::new(b"a/b/c"), Some(b"c"), b"a/b", Some(b"c"), None);
         t!(v: Path::new(b"a/b/\xFF"), Some(b"\xFF"), b"a/b", Some(b"\xFF"), None);
@@ -1008,7 +1008,7 @@ fn test_dir_path() {
 
     #[test]
     fn test_is_absolute() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $abs:expr, $rel:expr) => (
                 {
                     let path = Path::new($path);
@@ -1016,7 +1016,7 @@ macro_rules! t(
                     assert_eq!(path.is_relative(), $rel);
                 }
             )
-        );
+        }
         t!(s: "a/b/c", false, true);
         t!(s: "/a/b/c", true, false);
         t!(s: "a", false, true);
@@ -1029,7 +1029,7 @@ macro_rules! t(
 
     #[test]
     fn test_is_ancestor_of() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $dest:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -1037,7 +1037,7 @@ macro_rules! t(
                     assert_eq!(path.is_ancestor_of(&dest), $exp);
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", "a/b/c/d", true);
         t!(s: "a/b/c", "a/b/c", true);
@@ -1063,7 +1063,7 @@ macro_rules! t(
 
     #[test]
     fn test_ends_with_path() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $child:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -1078,7 +1078,7 @@ macro_rules! t(
                     assert_eq!(path.ends_with_path(&child), $exp);
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", "c", true);
         t!(s: "a/b/c", "d", false);
@@ -1102,7 +1102,7 @@ macro_rules! t(
 
     #[test]
     fn test_path_relative_from() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $other:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -1111,7 +1111,7 @@ macro_rules! t(
                     assert_eq!(res.as_ref().and_then(|x| x.as_str()), $exp);
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", "a/b", Some("c"));
         t!(s: "a/b/c", "a/b/d", Some("../c"));
@@ -1147,7 +1147,7 @@ macro_rules! t(
 
     #[test]
     fn test_components_iter() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -1173,7 +1173,7 @@ macro_rules! t(
                     assert_eq!(comps, exp)
                 }
             )
-        );
+        }
 
         t!(b: b"a/b/c", [b"a", b"b", b"c"]);
         t!(b: b"/\xFF/a/\x80", [b"\xFF", b"a", b"\x80"]);
@@ -1193,7 +1193,7 @@ macro_rules! t(
 
     #[test]
     fn test_str_components() {
-        macro_rules! t(
+        macro_rules! t {
             (b: $arg:expr, $exp:expr) => (
                 {
                     let path = Path::new($arg);
@@ -1205,7 +1205,7 @@ macro_rules! t(
                     assert_eq!(comps, exp);
                 }
             )
-        );
+        }
 
         t!(b: b"a/b/c", [Some("a"), Some("b"), Some("c")]);
         t!(b: b"/\xFF/a/\x80", [None, Some("a"), None]);
index 05129a7ab9da3988c352337e8980c836caec8521..4b5d793355b60137fabd2b321f25efb458076cb0 100644 (file)
@@ -1127,7 +1127,7 @@ macro_rules! t {
 
     #[test]
     fn test_parse_prefix() {
-        macro_rules! t(
+        macro_rules! t {
             ($path:expr, $exp:expr) => (
                 {
                     let path = $path;
@@ -1137,7 +1137,7 @@ macro_rules! t(
                             "parse_prefix(\"{}\"): expected {}, found {}", path, exp, res);
                 }
             )
-        );
+        }
 
         t!("\\\\SERVER\\share\\foo", Some(UNCPrefix(6,5)));
         t!("\\\\", None);
@@ -1326,7 +1326,7 @@ fn test_display_str() {
 
     #[test]
     fn test_display() {
-        macro_rules! t(
+        macro_rules! t {
             ($path:expr, $exp:expr, $expf:expr) => (
                 {
                     let path = Path::new($path);
@@ -1336,7 +1336,7 @@ macro_rules! t(
                     assert_eq!(f, $expf);
                 }
             )
-        );
+        }
 
         t!("foo", "foo", "foo");
         t!("foo\\bar", "foo\\bar", "bar");
@@ -1345,7 +1345,7 @@ macro_rules! t(
 
     #[test]
     fn test_components() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $op:ident, $exp:expr) => (
                 {
                     let path = $path;
@@ -1368,7 +1368,7 @@ macro_rules! t(
                     assert!(path.$op() == $exp);
                 }
             )
-        );
+        }
 
         t!(v: b"a\\b\\c", filename, Some(b"c"));
         t!(s: "a\\b\\c", filename_str, "c");
@@ -1468,7 +1468,7 @@ macro_rules! t(
 
     #[test]
     fn test_push() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $join:expr) => (
                 {
                     let path = $path;
@@ -1479,7 +1479,7 @@ macro_rules! t(
                     assert!(p1 == p2.join(join));
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", "..");
         t!(s: "\\a\\b\\c", "d");
@@ -1503,7 +1503,7 @@ macro_rules! t(
 
     #[test]
     fn test_push_path() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $push:expr, $exp:expr) => (
                 {
                     let mut p = Path::new($path);
@@ -1512,7 +1512,7 @@ macro_rules! t(
                     assert_eq!(p.as_str(), Some($exp));
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", "d", "a\\b\\c\\d");
         t!(s: "\\a\\b\\c", "d", "\\a\\b\\c\\d");
@@ -1555,7 +1555,7 @@ macro_rules! t(
 
     #[test]
     fn test_push_many() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $push:expr, $exp:expr) => (
                 {
                     let mut p = Path::new($path);
@@ -1570,7 +1570,7 @@ macro_rules! t(
                     assert_eq!(p.as_vec(), $exp);
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", ["d", "e"], "a\\b\\c\\d\\e");
         t!(s: "a\\b\\c", ["d", "\\e"], "\\e");
@@ -1584,7 +1584,7 @@ macro_rules! t(
 
     #[test]
     fn test_pop() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $left:expr, $right:expr) => (
                 {
                     let pstr = $path;
@@ -1605,7 +1605,7 @@ macro_rules! t(
                     assert!(result == $right);
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", "a\\b", true);
         t!(s: "a", ".", true);
@@ -1673,7 +1673,7 @@ fn test_join() {
 
     #[test]
     fn test_join_path() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $join:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -1682,7 +1682,7 @@ macro_rules! t(
                     assert_eq!(res.as_str(), Some($exp));
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", "..", "a\\b");
         t!(s: "\\a\\b\\c", "d", "\\a\\b\\c\\d");
@@ -1696,7 +1696,7 @@ macro_rules! t(
 
     #[test]
     fn test_join_many() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $join:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -1711,7 +1711,7 @@ macro_rules! t(
                     assert_eq!(res.as_vec(), $exp);
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", ["d", "e"], "a\\b\\c\\d\\e");
         t!(s: "a\\b\\c", ["..", "d"], "a\\b\\d");
@@ -1724,7 +1724,7 @@ macro_rules! t(
 
     #[test]
     fn test_with_helpers() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $op:ident, $arg:expr, $res:expr) => (
                 {
                     let pstr = $path;
@@ -1737,7 +1737,7 @@ macro_rules! t(
                             pstr, stringify!($op), arg, exp, res.as_str().unwrap());
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", with_filename, "d", "a\\b\\d");
         t!(s: ".", with_filename, "foo", "foo");
@@ -1809,7 +1809,7 @@ macro_rules! t(
 
     #[test]
     fn test_setters() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $set:ident, $with:ident, $arg:expr) => (
                 {
                     let path = $path;
@@ -1830,7 +1830,7 @@ macro_rules! t(
                     assert!(p1 == p2.$with(arg));
                 }
             )
-        );
+        }
 
         t!(v: b"a\\b\\c", set_filename, with_filename, b"d");
         t!(v: b"\\", set_filename, with_filename, b"foo");
@@ -1854,7 +1854,7 @@ macro_rules! t(
 
     #[test]
     fn test_getters() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $filename:expr, $dirname:expr, $filestem:expr, $ext:expr) => (
                 {
                     let path = $path;
@@ -1885,7 +1885,7 @@ macro_rules! t(
                     assert!(path.extension() == $ext);
                 }
             )
-        );
+        }
 
         t!(v: Path::new(b"a\\b\\c"), Some(b"c"), b"a\\b", Some(b"c"), None);
         t!(s: Path::new("a\\b\\c"), Some("c"), Some("a\\b"), Some("c"), None);
@@ -1920,7 +1920,7 @@ fn test_dir_path() {
 
     #[test]
     fn test_is_absolute() {
-        macro_rules! t(
+        macro_rules! t {
             ($path:expr, $abs:expr, $vol:expr, $cwd:expr, $rel:expr) => (
                 {
                     let path = Path::new($path);
@@ -1939,7 +1939,7 @@ macro_rules! t(
                             path.as_str().unwrap(), rel, b);
                 }
             )
-        );
+        }
         t!("a\\b\\c", false, false, false, true);
         t!("\\a\\b\\c", false, true, false, false);
         t!("a", false, false, false, true);
@@ -1960,7 +1960,7 @@ macro_rules! t(
 
     #[test]
     fn test_is_ancestor_of() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $dest:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -1972,7 +1972,7 @@ macro_rules! t(
                             path.as_str().unwrap(), dest.as_str().unwrap(), exp, res);
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", "a\\b\\c\\d", true);
         t!(s: "a\\b\\c", "a\\b\\c", true);
@@ -2063,7 +2063,7 @@ macro_rules! t(
 
     #[test]
     fn test_ends_with_path() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $child:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -2071,7 +2071,7 @@ macro_rules! t(
                     assert_eq!(path.ends_with_path(&child), $exp);
                 }
             );
-        );
+        }
 
         t!(s: "a\\b\\c", "c", true);
         t!(s: "a\\b\\c", "d", false);
@@ -2095,7 +2095,7 @@ macro_rules! t(
 
     #[test]
     fn test_path_relative_from() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $other:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -2108,7 +2108,7 @@ macro_rules! t(
                             res.as_ref().and_then(|x| x.as_str()));
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", "a\\b", Some("c"));
         t!(s: "a\\b\\c", "a\\b\\d", Some("..\\c"));
@@ -2229,7 +2229,7 @@ macro_rules! t(
 
     #[test]
     fn test_str_components() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -2243,7 +2243,7 @@ macro_rules! t(
                     assert_eq!(comps, exp);
                 }
             );
-        );
+        }
 
         t!(s: b"a\\b\\c", ["a", "b", "c"]);
         t!(s: "a\\b\\c", ["a", "b", "c"]);
@@ -2287,7 +2287,7 @@ macro_rules! t(
 
     #[test]
     fn test_components_iter() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -2299,7 +2299,7 @@ macro_rules! t(
                     assert_eq!(comps, exp);
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", [b"a", b"b", b"c"]);
         t!(s: ".", [b"."]);
@@ -2308,7 +2308,7 @@ macro_rules! t(
 
     #[test]
     fn test_make_non_verbatim() {
-        macro_rules! t(
+        macro_rules! t {
             ($path:expr, $exp:expr) => (
                 {
                     let path = Path::new($path);
@@ -2317,7 +2317,7 @@ macro_rules! t(
                     assert!(make_non_verbatim(&path) == exp);
                 }
             )
-        );
+        }
 
         t!(r"\a\b\c", Some(r"\a\b\c"));
         t!(r"a\b\c", Some(r"a\b\c"));
index 6ae6a238c952afb21c3b4af4247b5b68cd1b1409..a79a6e35ebcfd377ff74265cba1a9ec9d842d149 100644 (file)
@@ -23,11 +23,14 @@ mod imp {
     use path::Path;
     use rand::Rng;
     use rand::reader::ReaderRng;
-    use result::Result::{Ok, Err};
+    use result::Result::Ok;
     use slice::SliceExt;
     use mem;
     use os::errno;
 
+    // NOTE: for old macros; remove after the next snapshot
+    #[cfg(stage0)] use result::Result::Err;
+
     #[cfg(all(target_os = "linux",
               any(target_arch = "x86_64",
                   target_arch = "x86",
index 0f35500a04a737469e510e52e7e7212b1c56881c..bbc96d0b19f125fa91ee2297e062e905ed937c76 100644 (file)
@@ -13,8 +13,6 @@
 //! These macros call functions which are only accessible in the `rt` module, so
 //! they aren't defined anywhere outside of the `rt` module.
 
-#![macro_escape]
-
 macro_rules! rterrln {
     ($fmt:expr $($arg:tt)*) => ( {
         ::rt::util::dumb_print(format_args!(concat!($fmt, "\n") $($arg)*))
index 2b0639c570537f09a6cdb39a6ca8c8f7f580c0b1..e556888a470a288b100364bf8fd29aaae1ae94bf 100644 (file)
@@ -39,6 +39,8 @@
 pub mod backtrace;
 
 // Internals
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 mod macros;
 
 // These should be refactored/moved/made private over time
index d3b4fab96810bce9de4500ef8a9d32e912e6a6db..e0cbaa8ca50edbbb99c63a147445d1951f8551a7 100644 (file)
 //! will want to make use of some form of **interior mutability** through the
 //! `Cell` or `RefCell` types.
 
-#![macro_escape]
 #![stable]
 
 use prelude::v1::*;
 
 use cell::UnsafeCell;
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 pub mod scoped;
 
 // Sure wish we had macro hygiene, no?
index dc36fda3a020e9000b51ab6d0739417dd1cabf61..714b71d5dbd4e75364c4ee165a32dc8b8eafc10b 100644 (file)
@@ -38,7 +38,6 @@
 //! });
 //! ```
 
-#![macro_escape]
 #![unstable = "scoped TLS has yet to have wide enough use to fully consider \
                stabilizing its interface"]
 
index d48b0342b3bf72c5b3c40cef10eb1ede1eb799d5..ac1f0c5d803ac6a5b5b1e37a0a5fa7c51644c198 100644 (file)
 use option::Option;
 use option::Option::{Some, None};
 use num::Int;
-use result::Result;
-use result::Result::{Ok, Err};
+use result::Result::Ok;
+
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::Err;
 
 /// The number of nanoseconds in a microsecond.
 const NANOS_PER_MICRO: i32 = 1000;
index 727f4157c1e44b36ee01fd8afbf4c67e3082499f..7aa7c4fcfb3019be51d900134fb6adab37a0c81a 100644 (file)
@@ -476,7 +476,7 @@ pub struct Crate {
     pub attrs: Vec<Attribute>,
     pub config: CrateConfig,
     pub span: Span,
-    pub exported_macros: Vec<P<Item>>
+    pub exported_macros: Vec<MacroDef>,
 }
 
 pub type MetaItem = Spanned<MetaItem_>;
@@ -884,6 +884,7 @@ pub fn len(&self) -> uint {
         match *self {
             TtToken(_, token::DocComment(_)) => 2,
             TtToken(_, token::SubstNt(..)) => 2,
+            TtToken(_, token::SpecialVarNt(..)) => 2,
             TtToken(_, token::MatchNt(..)) => 3,
             TtDelimited(_, ref delimed) => {
                 delimed.tts.len() + 2
@@ -925,6 +926,12 @@ pub fn get_tt(&self, index: uint) -> TokenTree {
                          TtToken(sp, token::Ident(name, name_st))];
                 v[index]
             }
+            (&TtToken(sp, token::SpecialVarNt(var)), _) => {
+                let v = [TtToken(sp, token::Dollar),
+                         TtToken(sp, token::Ident(token::str_to_ident(var.as_str()),
+                                                  token::Plain))];
+                v[index]
+            }
             (&TtToken(sp, token::MatchNt(name, kind, name_st, kind_st)), _) => {
                 let v = [TtToken(sp, token::SubstNt(name, name_st)),
                          TtToken(sp, token::Colon),
@@ -1689,6 +1696,21 @@ pub enum InlinedItem {
     IIForeign(P<ForeignItem>),
 }
 
+/// A macro definition, in this crate or imported from another.
+///
+/// Not parsed directly, but created on macro import or `macro_rules!` expansion.
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
+pub struct MacroDef {
+    pub ident: Ident,
+    pub attrs: Vec<Attribute>,
+    pub id: NodeId,
+    pub span: Span,
+    pub imported_from: Option<Ident>,
+    pub export: bool,
+    pub use_locally: bool,
+    pub body: Vec<TokenTree>,
+}
+
 #[cfg(test)]
 mod test {
     use serialize::json;
index 3107508a96a5cda2ed6bc0aa400b195579f71344..34a193dffd3db5d1d7079a2bf16fa08f3c7e1aff 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
 #[macro_export]
 macro_rules! register_diagnostic {
     ($code:tt, $description:tt) => (__register_diagnostic! { $code, $description });
index 91cc8a24622054ceeb29af05662c51e0eea16ab2..91ae7396ea46920b4a97f1b188e30b9a714f2438 100644 (file)
@@ -16,6 +16,7 @@
 use codemap::{CodeMap, Span, ExpnId, ExpnInfo, NO_EXPANSION};
 use ext;
 use ext::expand;
+use ext::tt::macro_rules;
 use parse;
 use parse::parser;
 use parse::token;
 use std::collections::HashMap;
 use std::rc::Rc;
 
-// new-style macro! tt code:
-//
-//    MacResult, NormalTT, IdentTT
-//
-// also note that ast::Mac used to have a bunch of extraneous cases and
-// is now probably a redundant AST node, can be merged with
-// ast::MacInvocTT.
-
-pub struct MacroDef {
-    pub name: String,
-    pub ext: SyntaxExtension
-}
-
 pub trait ItemDecorator {
     fn expand(&self,
               ecx: &mut ExtCtxt,
@@ -140,13 +128,6 @@ fn expand<'cx>(&self,
 /// methods are spliced into the AST at the callsite of the macro (or
 /// just into the compiler's internal macro table, for `make_def`).
 pub trait MacResult {
-    /// Attempt to define a new macro.
-    // this should go away; the idea that a macro might expand into
-    // either a macro definition or an expression, depending on what
-    // the context wants, is kind of silly.
-    fn make_def(&mut self) -> Option<MacroDef> {
-        None
-    }
     /// Create an expression.
     fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
         None
@@ -328,13 +309,8 @@ pub enum SyntaxExtension {
     ///
     IdentTT(Box<IdentMacroExpander + 'static>, Option<Span>),
 
-    /// An ident macro that has two properties:
-    /// - it adds a macro definition to the environment, and
-    /// - the definition it adds doesn't introduce any new
-    ///   identifiers.
-    ///
-    /// `macro_rules!` is a LetSyntaxTT
-    LetSyntaxTT(Box<IdentMacroExpander + 'static>, Option<Span>),
+    /// Represents `macro_rules!` itself.
+    MacroRulesTT,
 }
 
 pub type NamedSyntaxExtension = (Name, SyntaxExtension);
@@ -364,8 +340,7 @@ fn builtin_normal_expander(f: MacroExpanderFn) -> SyntaxExtension {
     }
 
     let mut syntax_expanders = SyntaxEnv::new();
-    syntax_expanders.insert(intern("macro_rules"),
-                            LetSyntaxTT(box ext::tt::macro_rules::add_new_extension, None));
+    syntax_expanders.insert(intern("macro_rules"), MacroRulesTT);
     syntax_expanders.insert(intern("fmt"),
                             builtin_normal_expander(
                                 ext::fmt::expand_syntax_ext));
@@ -475,7 +450,7 @@ pub struct ExtCtxt<'a> {
 
     pub mod_path: Vec<ast::Ident> ,
     pub trace_mac: bool,
-    pub exported_macros: Vec<P<ast::Item>>,
+    pub exported_macros: Vec<ast::MacroDef>,
 
     pub syntax_env: SyntaxEnv,
     pub recursion_count: uint,
@@ -594,6 +569,17 @@ pub fn bt_pop(&mut self) {
             }
         }
     }
+
+    pub fn insert_macro(&mut self, def: ast::MacroDef) {
+        if def.export {
+            self.exported_macros.push(def.clone());
+        }
+        if def.use_locally {
+            let ext = macro_rules::compile(self, &def);
+            self.syntax_env.insert(def.ident.name, ext);
+        }
+    }
+
     /// Emit `msg` attached to `sp`, and stop compilation immediately.
     ///
     /// `span_err` should be strongly preferred where-ever possible:
index 84d30a99004a46f9f9a10fbfb041fd08989d1320..7cb7ee3d35533e43fa9fa4c8231cd131a3a3f3b4 100644 (file)
@@ -61,7 +61,7 @@ fn cs_ne(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P<Expr> {
             cx, span, substr)
     }
 
-    macro_rules! md (
+    macro_rules! md {
         ($name:expr, $f:ident) => { {
             let inline = cx.meta_word(span, InternedString::new("inline"));
             let attrs = vec!(cx.attribute(span, inline));
@@ -77,7 +77,7 @@ macro_rules! md (
                 })
             }
         } }
-    );
+    }
 
     let trait_def = TraitDef {
         span: span,
index f9c8d95b3084840bcafced9e9594fc059e89f9f6..c126238be8293f8a4e0e4efecc5ff827d49bf23c 100644 (file)
@@ -27,7 +27,7 @@ pub fn expand_deriving_ord<F>(cx: &mut ExtCtxt,
                               push: F) where
     F: FnOnce(P<Item>),
 {
-    macro_rules! md (
+    macro_rules! md {
         ($name:expr, $op:expr, $equal:expr) => { {
             let inline = cx.meta_word(span, InternedString::new("inline"));
             let attrs = vec!(cx.attribute(span, inline));
@@ -43,7 +43,7 @@ macro_rules! md (
                 })
             }
         } }
-    );
+    }
 
     let ordering_ty = Literal(Path::new(vec!["std", "cmp", "Ordering"]));
     let ret_ty = Literal(Path::new_(vec!["std", "option", "Option"],
index 14b19fee3df5e6963e152921a85cae0cd136dfc6..e72c83b67c89be435404aea043c5b9b6d0f54f62 100644 (file)
@@ -71,9 +71,11 @@ pub fn expand_meta_derive(cx: &mut ExtCtxt,
                     MetaNameValue(ref tname, _) |
                     MetaList(ref tname, _) |
                     MetaWord(ref tname) => {
-                        macro_rules! expand(($func:path) => ($func(cx, titem.span,
-                                                                   &**titem, item,
-                                                                   |i| push.call_mut((i,)))));
+                        macro_rules! expand {
+                            ($func:path) => ($func(cx, titem.span, &**titem, item,
+                                                   |i| push.call_mut((i,))))
+                        }
+
                         match tname.get() {
                             "Clone" => expand!(clone::expand_deriving_clone),
 
index b3e839b4fb648710ec4defcfd311779decccc2ca..212ec3b0903252ccd9f7c418cb473c39f6bbe1bf 100644 (file)
@@ -7,7 +7,6 @@
 // <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.
-use self::Either::*;
 
 use ast::{Block, Crate, DeclLocal, ExprMac, PatMac};
 use ast::{Local, Ident, MacInvocTT};
 use visit;
 use visit::Visitor;
 
-enum Either<L,R> {
-    Left(L),
-    Right(R)
-}
-
 pub fn expand_type(t: P<ast::Ty>,
                    fld: &mut MacroExpander,
                    impl_ty: Option<P<ast::Ty>>)
@@ -445,9 +439,9 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
             if valid_ident {
                 fld.cx.mod_push(it.ident);
             }
-            let macro_escape = contains_macro_escape(new_attrs[]);
+            let macro_use = contains_macro_use(fld, new_attrs[]);
             let result = with_exts_frame!(fld.cx.syntax_env,
-                                          macro_escape,
+                                          macro_use,
                                           noop_fold_item(it, fld));
             if valid_ident {
                 fld.cx.mod_pop();
@@ -527,15 +521,34 @@ fn expand_item_underscore(item: ast::Item_, fld: &mut MacroExpander) -> ast::Ite
     }
 }
 
-// does this attribute list contain "macro_escape" ?
-fn contains_macro_escape(attrs: &[ast::Attribute]) -> bool {
-    attr::contains_name(attrs, "macro_escape")
+// does this attribute list contain "macro_use" ?
+fn contains_macro_use(fld: &mut MacroExpander, attrs: &[ast::Attribute]) -> bool {
+    for attr in attrs.iter() {
+        let mut is_use = attr.check_name("macro_use");
+        if attr.check_name("macro_escape") {
+            fld.cx.span_warn(attr.span, "macro_escape is a deprecated synonym for macro_use");
+            is_use = true;
+            if let ast::AttrInner = attr.node.style {
+                fld.cx.span_help(attr.span, "consider an outer attribute, \
+                                             #[macro_use] mod ...");
+            }
+        };
+
+        if is_use {
+            match attr.node.value.node {
+                ast::MetaWord(..) => (),
+                _ => fld.cx.span_err(attr.span, "arguments to macro_use are not allowed here"),
+            }
+            return true;
+        }
+    }
+    false
 }
 
 // Support for item-position macro invocations, exactly the same
 // logic as for expression-position macro invocations.
-pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander)
-                       -> SmallVector<P<ast::Item>> {
+pub fn expand_item_mac(it: P<ast::Item>,
+                       fld: &mut MacroExpander) -> SmallVector<P<ast::Item>> {
     let (extname, path_span, tts) = match it.node {
         ItemMac(codemap::Spanned {
             node: MacInvocTT(ref pth, ref tts, _),
@@ -548,8 +561,8 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander)
 
     let extnamestr = token::get_ident(extname);
     let fm = fresh_mark();
-    let def_or_items = {
-        let mut expanded = match fld.cx.syntax_env.find(&extname.name) {
+    let items = {
+        let expanded = match fld.cx.syntax_env.find(&extname.name) {
             None => {
                 fld.cx.span_err(path_span,
                                 format!("macro undefined: '{}!'",
@@ -600,11 +613,10 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander)
                     let marked_tts = mark_tts(tts[], fm);
                     expander.expand(fld.cx, it.span, it.ident, marked_tts)
                 }
-                LetSyntaxTT(ref expander, span) => {
+                MacroRulesTT => {
                     if it.ident.name == parse::token::special_idents::invalid.name {
                         fld.cx.span_err(path_span,
-                                        format!("macro {}! expects an ident argument",
-                                                extnamestr.get())[]);
+                                        format!("macro_rules! expects an ident argument")[]);
                         return SmallVector::zero();
                     }
                     fld.cx.bt_push(ExpnInfo {
@@ -612,11 +624,26 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander)
                         callee: NameAndSpan {
                             name: extnamestr.get().to_string(),
                             format: MacroBang,
-                            span: span
+                            span: None,
                         }
                     });
-                    // DON'T mark before expansion:
-                    expander.expand(fld.cx, it.span, it.ident, tts)
+                    // DON'T mark before expansion.
+
+                    let def = ast::MacroDef {
+                        ident: it.ident,
+                        attrs: it.attrs.clone(),
+                        id: ast::DUMMY_NODE_ID,
+                        span: it.span,
+                        imported_from: None,
+                        export: attr::contains_name(it.attrs.as_slice(), "macro_export"),
+                        use_locally: true,
+                        body: tts,
+                    };
+                    fld.cx.insert_macro(def);
+
+                    // macro_rules! has a side effect but expands to nothing.
+                    fld.cx.bt_pop();
+                    return SmallVector::zero();
                 }
                 _ => {
                     fld.cx.span_err(it.span,
@@ -627,31 +654,17 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander)
             }
         };
 
-        match expanded.make_def() {
-            Some(def) => Left(def),
-            None => Right(expanded.make_items())
-        }
+        expanded.make_items()
     };
 
-    let items = match def_or_items {
-        Left(MacroDef { name, ext }) => {
-            // hidden invariant: this should only be possible as the
-            // result of expanding a LetSyntaxTT, and thus doesn't
-            // need to be marked. Not that it could be marked anyway.
-            // create issue to recommend refactoring here?
-            fld.cx.syntax_env.insert(intern(name[]), ext);
-            if attr::contains_name(it.attrs[], "macro_export") {
-                fld.cx.exported_macros.push(it);
-            }
-            SmallVector::zero()
-        }
-        Right(Some(items)) => {
+    let items = match items {
+        Some(items) => {
             items.into_iter()
                 .map(|i| mark_item(i, fm))
                 .flat_map(|i| fld.fold_item(i).into_iter())
                 .collect()
         }
-        Right(None) => {
+        None => {
             fld.cx.span_err(path_span,
                             format!("non-item macro in item position: {}",
                                     extnamestr.get())[]);
@@ -664,9 +677,6 @@ pub fn expand_item_mac(it: P<ast::Item>, fld: &mut MacroExpander)
 }
 
 /// Expand a stmt
-//
-// I don't understand why this returns a vector... it looks like we're
-// half done adding machinery to allow macros to expand into multiple statements.
 fn expand_stmt(s: Stmt, fld: &mut MacroExpander) -> SmallVector<P<Stmt>> {
     let (mac, style) = match s.node {
         StmtMac(mac, style) => (mac, style),
@@ -976,8 +986,8 @@ fn fold_ident(&mut self, id: Ident) -> Ident {
             ctxt: mtwt::apply_renames(self.renames, id.ctxt),
         }
     }
-    fn fold_mac(&mut self, macro: ast::Mac) -> ast::Mac {
-        fold::noop_fold_mac(macro, self)
+    fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+        fold::noop_fold_mac(mac, self)
     }
 }
 
@@ -1013,8 +1023,8 @@ fn fold_pat(&mut self, pat: P<ast::Pat>) -> P<ast::Pat> {
             _ => unreachable!()
         })
     }
-    fn fold_mac(&mut self, macro: ast::Mac) -> ast::Mac {
-        fold::noop_fold_mac(macro, self)
+    fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+        fold::noop_fold_mac(mac, self)
     }
 }
 
@@ -1175,31 +1185,17 @@ pub fn default(crate_name: String) -> ExpansionConfig {
     }
 }
 
-pub struct ExportedMacros {
-    pub crate_name: Ident,
-    pub macros: Vec<String>,
-}
-
 pub fn expand_crate(parse_sess: &parse::ParseSess,
                     cfg: ExpansionConfig,
                     // these are the macros being imported to this crate:
-                    imported_macros: Vec<ExportedMacros>,
+                    imported_macros: Vec<ast::MacroDef>,
                     user_exts: Vec<NamedSyntaxExtension>,
                     c: Crate) -> Crate {
     let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
     let mut expander = MacroExpander::new(&mut cx);
 
-    for ExportedMacros { crate_name, macros } in imported_macros.into_iter() {
-        let name = format!("<{} macros>", token::get_ident(crate_name));
-
-        for source in macros.into_iter() {
-            let item = parse::parse_item_from_source_str(name.clone(),
-                                                         source,
-                                                         expander.cx.cfg(),
-                                                         expander.cx.parse_sess())
-                    .expect("expected a serialized item");
-            expand_item_mac(item, &mut expander);
-        }
+    for def in imported_macros.into_iter() {
+        expander.cx.insert_macro(def);
     }
 
     for (name, extension) in user_exts.into_iter() {
@@ -1288,8 +1284,8 @@ struct MacroExterminator<'a>{
 }
 
 impl<'a, 'v> Visitor<'v> for MacroExterminator<'a> {
-    fn visit_mac(&mut self, macro: &ast::Mac) {
-        self.sess.span_diagnostic.span_bug(macro.span,
+    fn visit_mac(&mut self, mac: &ast::Mac) {
+        self.sess.span_diagnostic.span_bug(mac.span,
                                            "macro exterminator: expected AST \
                                            with no macro invocations");
     }
@@ -1298,7 +1294,7 @@ fn visit_mac(&mut self, macro: &ast::Mac) {
 
 #[cfg(test)]
 mod test {
-    use super::{pattern_bindings, expand_crate, contains_macro_escape};
+    use super::{pattern_bindings, expand_crate, contains_macro_use};
     use super::{PatIdentFinder, IdentRenamer, PatIdentRenamer, ExpansionConfig};
     use ast;
     use ast::{Attribute_, AttrOuter, MetaWord, Name};
@@ -1395,9 +1391,9 @@ fn test_ecfg() -> ExpansionConfig {
         expand_crate(&sess,test_ecfg(),vec!(),vec!(),crate_ast);
     }
 
-    // macro_escape modules should allow macros to escape
+    // macro_use modules should allow macros to escape
     #[test] fn macros_can_escape_flattened_mods_test () {
-        let src = "#[macro_escape] mod foo {macro_rules! z (() => (3+4));}\
+        let src = "#[macro_use] mod foo {macro_rules! z (() => (3+4));}\
                    fn inty() -> int { z!() }".to_string();
         let sess = parse::new_parse_sess();
         let crate_ast = parse::parse_crate_from_source_str(
@@ -1407,16 +1403,6 @@ fn test_ecfg() -> ExpansionConfig {
         expand_crate(&sess, test_ecfg(), vec!(), vec!(), crate_ast);
     }
 
-    #[test] fn test_contains_flatten (){
-        let attr1 = make_dummy_attr ("foo");
-        let attr2 = make_dummy_attr ("bar");
-        let escape_attr = make_dummy_attr ("macro_escape");
-        let attrs1 = vec!(attr1.clone(), escape_attr, attr2.clone());
-        assert_eq!(contains_macro_escape(attrs1[]),true);
-        let attrs2 = vec!(attr1,attr2);
-        assert_eq!(contains_macro_escape(attrs2[]),false);
-    }
-
     // make a MetaWord outer attribute with the given name
     fn make_dummy_attr(s: &str) -> ast::Attribute {
         Spanned {
index 08014dc13383f99d822b815a781ffe55bdccf5c6..9837c8088fa4507a38f6ec9a523384009787d53c 100644 (file)
@@ -11,7 +11,7 @@
 use ast::{Ident, TtDelimited, TtSequence, TtToken};
 use ast;
 use codemap::{Span, DUMMY_SP};
-use ext::base::{ExtCtxt, MacResult, MacroDef};
+use ext::base::{ExtCtxt, MacResult, SyntaxExtension};
 use ext::base::{NormalTT, TTMacroExpander};
 use ext::tt::macro_parser::{Success, Error, Failure};
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
@@ -38,8 +38,8 @@ impl<'a> ParserAnyMacro<'a> {
     /// Make sure we don't have any tokens left to parse, so we don't
     /// silently drop anything. `allow_semi` is so that "optional"
     /// semicolons at the end of normal expressions aren't complained
-    /// about e.g. the semicolon in `macro_rules! kapow( () => {
-    /// panic!(); } )` doesn't get picked up by .parse_expr(), but it's
+    /// about e.g. the semicolon in `macro_rules! kapow { () => {
+    /// panic!(); } }` doesn't get picked up by .parse_expr(), but it's
     /// allowed to be there.
     fn ensure_complete_parse(&self, allow_semi: bool) {
         let mut parser = self.parser.borrow_mut();
@@ -110,6 +110,7 @@ fn make_stmt(self: Box<ParserAnyMacro<'a>>) -> Option<P<ast::Stmt>> {
 
 struct MacroRulesMacroExpander {
     name: Ident,
+    imported_from: Option<Ident>,
     lhses: Vec<Rc<NamedMatch>>,
     rhses: Vec<Rc<NamedMatch>>,
 }
@@ -123,25 +124,18 @@ fn expand<'cx>(&self,
         generic_extension(cx,
                           sp,
                           self.name,
+                          self.imported_from,
                           arg,
                           self.lhses[],
                           self.rhses[])
     }
 }
 
-struct MacroRulesDefiner {
-    def: Option<MacroDef>
-}
-impl MacResult for MacroRulesDefiner {
-    fn make_def(&mut self) -> Option<MacroDef> {
-        Some(self.def.take().expect("empty MacroRulesDefiner"))
-    }
-}
-
 /// Given `lhses` and `rhses`, this is the new macro we create
 fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                           sp: Span,
                           name: Ident,
+                          imported_from: Option<Ident>,
                           arg: &[ast::TokenTree],
                           lhses: &[Rc<NamedMatch>],
                           rhses: &[Rc<NamedMatch>])
@@ -165,6 +159,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
             };
             // `None` is because we're not interpolating
             let mut arg_rdr = new_tt_reader(&cx.parse_sess().span_diagnostic,
+                                            None,
                                             None,
                                             arg.iter()
                                                .map(|x| (*x).clone())
@@ -186,6 +181,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                 // rhs has holes ( `$id` and `$(...)` that need filled)
                 let trncbr = new_tt_reader(&cx.parse_sess().span_diagnostic,
                                            Some(named_matches),
+                                           imported_from,
                                            rhs);
                 let p = Parser::new(cx.parse_sess(), cx.cfg(), box trncbr);
                 // Let the context choose how to interpret the result.
@@ -212,14 +208,9 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
 //
 // Holy self-referential!
 
-/// This procedure performs the expansion of the
-/// macro_rules! macro. It parses the RHS and adds
-/// an extension to the current context.
-pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
-                              sp: Span,
-                              name: Ident,
-                              arg: Vec<ast::TokenTree> )
-                              -> Box<MacResult+'cx> {
+/// Converts a `macro_rules!` invocation into a syntax extension.
+pub fn compile<'cx>(cx: &'cx mut ExtCtxt,
+                    def: &ast::MacroDef) -> SyntaxExtension {
 
     let lhs_nm =  gensym_ident("lhs");
     let rhs_nm =  gensym_ident("rhs");
@@ -256,7 +247,8 @@ pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
     // Parse the macro_rules! invocation (`none` is for no interpolations):
     let arg_reader = new_tt_reader(&cx.parse_sess().span_diagnostic,
                                    None,
-                                   arg.clone());
+                                   None,
+                                   def.body.clone());
     let argument_map = parse_or_else(cx.parse_sess(),
                                      cx.cfg(),
                                      arg_reader,
@@ -265,24 +257,20 @@ pub fn add_new_extension<'cx>(cx: &'cx mut ExtCtxt,
     // Extract the arguments:
     let lhses = match *argument_map[lhs_nm] {
         MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
-        _ => cx.span_bug(sp, "wrong-structured lhs")
+        _ => cx.span_bug(def.span, "wrong-structured lhs")
     };
 
     let rhses = match *argument_map[rhs_nm] {
         MatchedSeq(ref s, _) => /* FIXME (#2543) */ (*s).clone(),
-        _ => cx.span_bug(sp, "wrong-structured rhs")
+        _ => cx.span_bug(def.span, "wrong-structured rhs")
     };
 
     let exp = box MacroRulesMacroExpander {
-        name: name,
+        name: def.ident,
+        imported_from: def.imported_from,
         lhses: lhses,
         rhses: rhses,
     };
 
-    box MacroRulesDefiner {
-        def: Some(MacroDef {
-            name: token::get_ident(name).to_string(),
-            ext: NormalTT(exp, Some(sp))
-        })
-    } as Box<MacResult+'cx>
+    NormalTT(exp, Some(def.span))
 }
index 86e81ede8b0fe3a480b391d4f5477b0a05fa7de9..e4e6f5ac6b0f0f0c4953b6ab426eb8cb914d2e31 100644 (file)
@@ -15,7 +15,7 @@
 use diagnostic::SpanHandler;
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
 use parse::token::{Eof, DocComment, Interpolated, MatchNt, SubstNt};
-use parse::token::{Token, NtIdent};
+use parse::token::{Token, NtIdent, SpecialMacroVar};
 use parse::token;
 use parse::lexer::TokenAndSpan;
 
@@ -39,6 +39,10 @@ pub struct TtReader<'a> {
     stack: Vec<TtFrame>,
     /* for MBE-style macro transcription */
     interpolations: HashMap<Ident, Rc<NamedMatch>>,
+    imported_from: Option<Ident>,
+
+    // Some => return imported_from as the next token
+    crate_name_next: Option<Span>,
     repeat_idx: Vec<uint>,
     repeat_len: Vec<uint>,
     /* cached: */
@@ -53,6 +57,7 @@ pub struct TtReader<'a> {
 /// should) be none.
 pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
                          interp: Option<HashMap<Ident, Rc<NamedMatch>>>,
+                         imported_from: Option<Ident>,
                          src: Vec<ast::TokenTree> )
                          -> TtReader<'a> {
     let mut r = TtReader {
@@ -71,6 +76,8 @@ pub fn new_tt_reader<'a>(sp_diag: &'a SpanHandler,
             None => HashMap::new(),
             Some(x) => x,
         },
+        imported_from: imported_from,
+        crate_name_next: None,
         repeat_idx: Vec::new(),
         repeat_len: Vec::new(),
         desugar_doc_comments: false,
@@ -162,6 +169,14 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
         sp: r.cur_span.clone(),
     };
     loop {
+        match r.crate_name_next.take() {
+            None => (),
+            Some(sp) => {
+                r.cur_span = sp;
+                r.cur_tok = token::Ident(r.imported_from.unwrap(), token::Plain);
+                return ret_val;
+            },
+        }
         let should_pop = match r.stack.last() {
             None => {
                 assert_eq!(ret_val.tok, token::Eof);
@@ -307,6 +322,18 @@ pub fn tt_next_token(r: &mut TtReader) -> TokenAndSpan {
                    sep: None
                 });
             }
+            TtToken(sp, token::SpecialVarNt(SpecialMacroVar::CrateMacroVar)) => {
+                r.stack.last_mut().unwrap().idx += 1;
+
+                if r.imported_from.is_some() {
+                    r.cur_span = sp;
+                    r.cur_tok = token::ModSep;
+                    r.crate_name_next = Some(sp);
+                    return ret_val;
+                }
+
+                // otherwise emit nothing and proceed to the next token
+            }
             TtToken(sp, tok) => {
                 r.cur_span = sp;
                 r.cur_tok = tok;
index 4dc4e69aa558884ec77137b6c96204035a002ade..43e4039330837c157408da3cb1e30f20d7f9af0a 100644 (file)
 // if you change this list without updating src/doc/reference.md, @cmr will be sad
 static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
     ("globs", Accepted),
-    ("macro_rules", Active),
+    ("macro_rules", Accepted),
     ("struct_variant", Accepted),
     ("asm", Active),
     ("managed_boxes", Removed),
     ("non_ascii_idents", Active),
     ("thread_local", Active),
     ("link_args", Active),
-    ("phase", Active),
+    ("phase", Active),  // NOTE(stage0): switch to Removed after next snapshot
     ("plugin_registrar", Active),
     ("log_syntax", Active),
     ("trace_macros", Active),
@@ -74,6 +74,8 @@
     ("if_let", Accepted),
     ("while_let", Accepted),
 
+    ("plugin", Active),
+
     // A temporary feature gate used to enable parser extensions needed
     // to bootstrap fix for #5723.
     ("issue_5723_bootstrap", Accepted),
@@ -161,32 +163,11 @@ struct MacroVisitor<'a> {
 }
 
 impl<'a, 'v> Visitor<'v> for MacroVisitor<'a> {
-    fn visit_view_item(&mut self, i: &ast::ViewItem) {
-        match i.node {
-            ast::ViewItemExternCrate(..) => {
-                for attr in i.attrs.iter() {
-                    if attr.name().get() == "phase"{
-                        self.context.gate_feature("phase", attr.span,
-                                          "compile time crate loading is \
-                                           experimental and possibly buggy");
-                    }
-                }
-            },
-            _ => { }
-        }
-        visit::walk_view_item(self, i)
-    }
-
-    fn visit_mac(&mut self, macro: &ast::Mac) {
-        let ast::MacInvocTT(ref path, _, _) = macro.node;
+    fn visit_mac(&mut self, mac: &ast::Mac) {
+        let ast::MacInvocTT(ref path, _, _) = mac.node;
         let id = path.segments.last().unwrap().identifier;
 
-        if id == token::str_to_ident("macro_rules") {
-            self.context.gate_feature("macro_rules", path.span, "macro definitions are \
-                not stable enough for use and are subject to change");
-        }
-
-        else if id == token::str_to_ident("asm") {
+        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");
         }
@@ -233,10 +214,10 @@ fn visit_view_item(&mut self, i: &ast::ViewItem) {
             ast::ViewItemUse(..) => {}
             ast::ViewItemExternCrate(..) => {
                 for attr in i.attrs.iter() {
-                    if attr.name().get() == "phase"{
-                        self.gate_feature("phase", attr.span,
-                                          "compile time crate loading is \
-                                           experimental and possibly buggy");
+                    if attr.check_name("plugin") {
+                        self.gate_feature("plugin", attr.span,
+                                          "compiler plugins are experimental \
+                                           and possibly buggy");
                     }
                 }
             }
index 2999ef7ee86a68790e23d6164bac902729fc5d79..c45a4005339baea337116a1494daf44e2da0d048 100644 (file)
@@ -194,13 +194,13 @@ fn fold_local(&mut self, l: P<Local>) -> P<Local> {
         noop_fold_local(l, self)
     }
 
-    fn fold_mac(&mut self, _macro: Mac) -> Mac {
+    fn fold_mac(&mut self, _mac: Mac) -> Mac {
         panic!("fold_mac disabled by default");
         // NB: see note about macros above.
         // if you really want a folder that
         // works on macros, use this
         // definition in your trait impl:
-        // fold::noop_fold_mac(_macro, self)
+        // fold::noop_fold_mac(_mac, self)
     }
 
     fn fold_explicit_self(&mut self, es: ExplicitSelf) -> ExplicitSelf {
@@ -1104,7 +1104,7 @@ pub fn noop_fold_mod<T: Folder>(Mod {inner, view_items, items}: Mod, folder: &mu
     }
 }
 
-pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, exported_macros, span}: Crate,
+pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_macros, span}: Crate,
                                   folder: &mut T) -> Crate {
     let config = folder.fold_meta_items(config);
 
@@ -1135,6 +1135,10 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, exported_macros,
         }, Vec::new(), span)
     };
 
+    for def in exported_macros.iter_mut() {
+        def.id = folder.new_id(def.id);
+    }
+
     Crate {
         module: module,
         attrs: attrs,
@@ -1472,8 +1476,8 @@ impl Folder for ToZzIdentFolder {
         fn fold_ident(&mut self, _: ast::Ident) -> ast::Ident {
             token::str_to_ident("zz")
         }
-        fn fold_mac(&mut self, macro: ast::Mac) -> ast::Mac {
-            fold::noop_fold_mac(macro, self)
+        fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
+            fold::noop_fold_mac(mac, self)
         }
     }
 
index 18cdb3fc6478949180903e8481d04506c0f1a269..b7bfd346d506b96fffdfbbb0e535d273a0969255 100644 (file)
 
 extern crate arena;
 extern crate fmt_macros;
-#[phase(plugin, link)] extern crate log;
 extern crate serialize;
 extern crate term;
 extern crate libc;
 
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
+
 extern crate "serialize" as rustc_serialize; // used by deriving
 
 pub mod util {
index 8598571e5c37a7f41cebe2aeb1942da2a1968387..b0969a573e66b3cf35e1cb5a0573c079e85228de 100644 (file)
 use std::str;
 use std::iter;
 
-pub mod lexer;
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 pub mod parser;
+
+pub mod lexer;
 pub mod token;
 pub mod attr;
 
@@ -166,6 +169,8 @@ pub fn parse_stmt_from_source_str(name: String,
 
 // Note: keep in sync with `with_hygiene::parse_tts_from_source_str`
 // until #16472 is resolved.
+//
+// Warning: This parses with quote_depth > 0, which is not the default.
 pub fn parse_tts_from_source_str(name: String,
                                  source: String,
                                  cfg: ast::CrateConfig,
@@ -291,7 +296,7 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
 pub fn tts_to_parser<'a>(sess: &'a ParseSess,
                          tts: Vec<ast::TokenTree>,
                          cfg: ast::CrateConfig) -> Parser<'a> {
-    let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts);
+    let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, None, tts);
     Parser::new(sess, cfg, box trdr)
 }
 
@@ -307,6 +312,8 @@ pub mod with_hygiene {
 
     // Note: keep this in sync with `super::parse_tts_from_source_str` until
     // #16472 is resolved.
+    //
+    // Warning: This parses with quote_depth > 0, which is not the default.
     pub fn parse_tts_from_source_str(name: String,
                                      source: String,
                                      cfg: ast::CrateConfig,
index 58b08757cdfb6f3d0b4fbbcf01527bd13a3d2872..cdfbd2c74b6af296f4d0346c20df6ac5730fe649 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
 pub use self::PathParsingMode::*;
 use self::ItemOrViewItem::*;
 
@@ -74,8 +72,8 @@
 use parse::common::{SeqSep, seq_sep_none, seq_sep_trailing_allowed};
 use parse::lexer::{Reader, TokenAndSpan};
 use parse::obsolete::*;
-use parse::token::{self, MatchNt, SubstNt, InternedString};
-use parse::token::{keywords, special_idents};
+use parse::token::{self, MatchNt, SubstNt, SpecialVarNt, InternedString};
+use parse::token::{keywords, special_idents, SpecialMacroVar};
 use parse::{new_sub_parser_from_file, ParseSess};
 use print::pprust;
 use ptr::P;
@@ -2739,6 +2737,9 @@ fn parse_non_delim_tt_tok(p: &mut Parser) -> TokenTree {
                                    op: repeat,
                                    num_captures: name_num
                                }))
+                } else if p.token.is_keyword_allow_following_colon(keywords::Crate) {
+                    p.bump();
+                    TtToken(sp, SpecialVarNt(SpecialMacroVar::CrateMacroVar))
                 } else {
                     // A nonterminal that matches or not
                     let namep = match p.token { token::Ident(_, p) => p, _ => token::Plain };
@@ -3881,13 +3882,13 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                                                                   &mut stmts,
                                                                   &mut expr);
                         }
-                        StmtMac(macro, MacStmtWithoutBraces) => {
+                        StmtMac(mac, MacStmtWithoutBraces) => {
                             // statement macro without braces; might be an
                             // expr depending on whether a semicolon follows
                             match self.token {
                                 token::Semi => {
                                     stmts.push(P(Spanned {
-                                        node: StmtMac(macro,
+                                        node: StmtMac(mac,
                                                       MacStmtWithSemicolon),
                                         span: span,
                                     }));
@@ -3896,10 +3897,16 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                                 _ => {
                                     let e = self.mk_mac_expr(span.lo,
                                                              span.hi,
+<<<<<<< HEAD
                                                              macro.and_then(|m| m.node));
                                     let e = self.parse_dot_or_call_expr_with(e);
                                     let e = self.parse_more_binops(e, 0);
                                     let e = self.parse_assign_expr_with(e);
+=======
+                                                             mac.and_then(|m| m.node));
+                                    let e =
+                                        self.parse_dot_or_call_expr_with(e);
+>>>>>>> kmc/macro-reform
                                     self.handle_expression_like_statement(
                                         e,
                                         ast::DUMMY_NODE_ID,
@@ -6026,6 +6033,10 @@ fn parse_use(&mut self) -> ViewItem_ {
     fn parse_view_path(&mut self) -> P<ViewPath> {
         let lo = self.span.lo;
 
+        // Allow a leading :: because the paths are absolute either way.
+        // This occurs with "use $crate::..." in macros.
+        self.eat(&token::ModSep);
+
         if self.check(&token::OpenDelim(token::Brace)) {
             // use {foo,bar}
             let idents = self.parse_unspanned_seq(
index b7e89b32b709e6f3c73cb20e5e6da9c1260ca3fe..094aacf3207fcb0a14be6207f51d79f21d623275 100644 (file)
@@ -61,6 +61,21 @@ pub enum IdentStyle {
     Plain,
 }
 
+#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Show, Copy)]
+pub enum SpecialMacroVar {
+    /// `$crate` will be filled in with the name of the crate a macro was
+    /// imported from, if any.
+    CrateMacroVar,
+}
+
+impl SpecialMacroVar {
+    pub fn as_str(self) -> &'static str {
+        match self {
+            SpecialMacroVar::CrateMacroVar => "crate",
+        }
+    }
+}
+
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Show, Copy)]
 pub enum Lit {
     Byte(ast::Name),
@@ -143,6 +158,8 @@ pub enum Token {
     // In right-hand-sides of MBE macros:
     /// A syntactic variable that will be filled in by macro expansion.
     SubstNt(ast::Ident, IdentStyle),
+    /// A macro variable with special meaning.
+    SpecialVarNt(SpecialMacroVar),
 
     // Junk. These carry no data because we don't really care about the data
     // they *would* carry, and don't really want to allocate a new ident for
@@ -265,6 +282,13 @@ pub fn is_keyword(&self, kw: keywords::Keyword) -> bool {
         }
     }
 
+    pub fn is_keyword_allow_following_colon(&self, kw: keywords::Keyword) -> bool {
+        match *self {
+            Ident(sid, _) => { kw.to_name() == sid.name }
+            _ => { false }
+        }
+    }
+
     /// Returns `true` if the token is either a special identifier, or a strict
     /// or reserved keyword.
     #[allow(non_upper_case_globals)]
@@ -550,6 +574,7 @@ pub mod keywords {
         (56,                         Abstract,   "abstract");
         (57,                         Final,      "final");
         (58,                         Override,   "override");
+        (59,                         Macro,      "macro");
     }
 }
 
index 553e717f6921dcdbd60d959cb1390b10db3e4139..402583b60fae5387e6c89055f875408341539c5e 100644 (file)
@@ -272,6 +272,8 @@ pub fn token_to_string(tok: &Token) -> String {
         token::Comment              => "/* */".to_string(),
         token::Shebang(s)           => format!("/* shebang: {}*/", s.as_str()),
 
+        token::SpecialVarNt(var)    => format!("${}", var.as_str()),
+
         token::Interpolated(ref nt) => match *nt {
             token::NtExpr(ref e)  => expr_to_string(&**e),
             token::NtMeta(ref e)  => meta_item_to_string(&**e),
index 5a4d0cc3bd896cb69c58a07513bc5b2e4674b910..4ef7eb97a218946e8c16b2b24d70c91d7617aff4 100644 (file)
@@ -65,12 +65,8 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
                                            Some((actual_crate_name, ast::CookedStr)),
                                            ast::DUMMY_NODE_ID),
             attrs: vec!(
-                attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item(
-                        InternedString::new("phase"),
-                        vec!(
-                            attr::mk_word_item(InternedString::new("plugin")),
-                            attr::mk_word_item(InternedString::new("link")
-                        ))))),
+                attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
+                        InternedString::new("macro_use")))),
             vis: ast::Inherited,
             span: DUMMY_SP
         });
@@ -82,16 +78,6 @@ fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
         // don't add #![no_std] here, that will block the prelude injection later.
         // Add it during the prelude injection instead.
 
-        // Add #![feature(phase)] here, because we use #[phase] on extern crate std.
-        let feat_phase_attr = attr::mk_attr_inner(attr::mk_attr_id(),
-                                                  attr::mk_list_item(
-                                  InternedString::new("feature"),
-                                  vec![attr::mk_word_item(InternedString::new("phase"))],
-                              ));
-        // std_inject runs after feature checking so manually mark this attr
-        attr::mark_used(&feat_phase_attr);
-        krate.attrs.push(feat_phase_attr);
-
         krate
     }
 }
index cc71bafbbe5e2a0d2a70b6a40963a0d14d3fc01e..3f91304dcc5f21c528b2cfcdcee0c570109f10de 100644 (file)
@@ -115,13 +115,13 @@ fn visit_lifetime_def(&mut self, lifetime: &'v LifetimeDef) {
     fn visit_explicit_self(&mut self, es: &'v ExplicitSelf) {
         walk_explicit_self(self, es)
     }
-    fn visit_mac(&mut self, _macro: &'v Mac) {
+    fn visit_mac(&mut self, _mac: &'v Mac) {
         panic!("visit_mac disabled by default");
         // NB: see note about macros above.
         // if you really want a visitor that
         // works on macros, use this
         // definition in your trait impl:
-        // visit::walk_mac(self, _macro)
+        // visit::walk_mac(self, _mac)
     }
     fn visit_path(&mut self, path: &'v Path, _id: ast::NodeId) {
         walk_path(self, path)
@@ -334,7 +334,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
                 visitor.visit_trait_item(method)
             }
         }
-        ItemMac(ref macro) => visitor.visit_mac(macro),
+        ItemMac(ref mac) => visitor.visit_mac(mac),
     }
     for attr in item.attrs.iter() {
         visitor.visit_attribute(attr);
@@ -538,7 +538,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
                 visitor.visit_pat(&**postpattern)
             }
         }
-        PatMac(ref macro) => visitor.visit_mac(macro),
+        PatMac(ref mac) => visitor.visit_mac(mac),
     }
 }
 
@@ -738,7 +738,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) {
         StmtExpr(ref expression, _) | StmtSemi(ref expression, _) => {
             visitor.visit_expr(&**expression)
         }
-        StmtMac(ref macro, _) => visitor.visit_mac(&**macro),
+        StmtMac(ref mac, _) => visitor.visit_mac(&**mac),
     }
 }
 
@@ -885,7 +885,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
         ExprRet(ref optional_expression) => {
             walk_expr_opt(visitor, optional_expression)
         }
-        ExprMac(ref macro) => visitor.visit_mac(macro),
+        ExprMac(ref mac) => visitor.visit_mac(mac),
         ExprParen(ref subexpression) => {
             visitor.visit_expr(&**subexpression)
         }
index 3a442080077f33217ebe8d1a4b65f00e8cfc60d4..dd42bede13ac3e69d8f35850bad010214a9e9e24 100644 (file)
 
 #![deny(missing_docs)]
 
-#[phase(plugin, link)] extern crate log;
+#[cfg(stage0)]
+#[phase(plugin, link)]
+extern crate log;
+
+#[cfg(not(stage0))]
+#[macro_use]
+extern crate log;
 
 pub use terminfo::TerminfoTerminal;
 #[cfg(windows)]
index fe96d7b8b7d013c240f81e9d71f04e598b42ea6d..5f0111c7d7a84de51191dff892f86531c099cc44 100644 (file)
 /// Parse a compiled terminfo entry, using long capability names if `longnames` is true
 pub fn parse(file: &mut io::Reader, longnames: bool)
              -> Result<Box<TermInfo>, String> {
-    macro_rules! try( ($e:expr) => (
+    macro_rules! try { ($e:expr) => (
         match $e {
             Ok(e) => e,
             Err(e) => return Err(format!("{}", e))
         }
-    ) );
+    ) }
 
     let bnames;
     let snames;
index 3fb2211eff23a367464e4525b15ac3c83a1e230a..0419d85d3914ec32bde0b610532ce62649a5bbcc 100644 (file)
@@ -32,7 +32,7 @@
        html_root_url = "http://doc.rust-lang.org/nightly/")]
 
 #![allow(unknown_features)]
-#![feature(asm, macro_rules, phase, globs, slicing_syntax)]
+#![feature(asm, globs, slicing_syntax)]
 #![feature(unboxed_closures, default_type_params)]
 #![feature(old_orphan_check)]
 
index c80a7643e01ac78e260f6a986942be25fc0aa44f..5510d3e2e0df18386d82ee8c10183186d608ea70 100644 (file)
@@ -11,8 +11,7 @@
 // no-prefer-dynamic
 
 #![crate_type = "rlib"]
-#![feature(phase)]
 
-#[phase(plugin)] extern crate "issue-13560-1" as t1;
-#[phase(plugin, link)] extern crate "issue-13560-2" as t2;
+#[macro_use] #[no_link] extern crate "issue-13560-1" as t1;
+#[macro_use] extern crate "issue-13560-2" as t2;
 
index add54ed01e00e618c416c751b68fa6703d8f2ef4..097a5827fc4be1fe937301a2e97da7c71837a616 100644 (file)
 
 // force-host
 
-#![feature(phase, plugin_registrar)]
+#![feature(plugin_registrar)]
 
 extern crate syntax;
 
 // Load rustc as a plugin to get macros
-#[phase(plugin, link)]
+#[macro_use]
 extern crate rustc;
 
 use syntax::ast;
index 6c78cdce28ac4b12d75b3cf1610a00cf0cf2cab7..01ef08c475234c3a402dd66648755eed2ce5c3ef 100644 (file)
 
 // force-host
 
-#![feature(phase, plugin_registrar)]
+#![feature(plugin_registrar)]
 
 extern crate syntax;
 
 // Load rustc as a plugin to get macros
-#[phase(plugin, link)]
+#[macro_use]
 extern crate rustc;
 
 use syntax::ast;
index 82af18b189b68f12f0284aed0e60c53c56cba2b9..708830d02598643bed2c33caa802baccd910b628 100644 (file)
@@ -10,9 +10,6 @@
 #![crate_name="lint_stability"]
 #![crate_type = "lib"]
 
-#![feature(macro_rules)]
-#![macro_escape]
-
 #[deprecated]
 pub fn deprecated() {}
 #[deprecated="text"]
@@ -181,16 +178,16 @@ pub enum Enum {
 pub struct LockedTupleStruct(pub int);
 
 #[macro_export]
-macro_rules! macro_test(
+macro_rules! macro_test {
     () => (deprecated());
-);
+}
 
 #[macro_export]
-macro_rules! macro_test_arg(
+macro_rules! macro_test_arg {
     ($func:expr) => ($func);
-);
+}
 
 #[macro_export]
-macro_rules! macro_test_arg_nested(
+macro_rules! macro_test_arg_nested {
     ($func:ident) => (macro_test_arg!($func()));
-);
+}
index 399dfb9fa9a5bbc40bf6c955abfd089ea41ee421..67037a3ac9e08cde559758543ff5280e342b3849 100644 (file)
@@ -8,8 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(phase)]
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
 
 pub fn foo<T>() {
     fn death() -> int { panic!() }
diff --git a/src/test/auxiliary/macro_crate_MacroRulesTT.rs b/src/test/auxiliary/macro_crate_MacroRulesTT.rs
new file mode 100644 (file)
index 0000000..d50c27a
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014 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.
+
+// force-host
+
+#![feature(plugin_registrar)]
+
+extern crate syntax;
+extern crate rustc;
+
+use syntax::parse::token;
+use syntax::ext::base::MacroRulesTT;
+use rustc::plugin::Registry;
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_syntax_extension(token::intern("bogus"), MacroRulesTT);
+}
index ad3e72f5fa2219cca0706ff5ee853cf29d2b49a5..4f55ac4f65fd48ee9e56f8164fc8b73dcba93419 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 #[macro_export]
-macro_rules! make_a_5(
+macro_rules! make_a_5 {
     () => (5)
-);
+}
diff --git a/src/test/auxiliary/macro_crate_nonterminal.rs b/src/test/auxiliary/macro_crate_nonterminal.rs
new file mode 100644 (file)
index 0000000..922efc1
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2014 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.
+
+pub fn increment(x: uint) -> uint {
+    x + 1
+}
+
+#[macro_export]
+macro_rules! increment {
+    ($x:expr) => ($crate::increment($x))
+}
+
+pub fn check_local() {
+    assert_eq!(increment!(3), 4);
+}
index 39c4e83c4b9dae3f2ac57aa24a419872a67c342a..99f02cf2d58ba02ca15d5f74e348ea2d8a1fd51c 100644 (file)
@@ -10,7 +10,7 @@
 
 // force-host
 
-#![feature(plugin_registrar, macro_rules, quote)]
+#![feature(plugin_registrar, quote)]
 
 extern crate syntax;
 extern crate rustc;
@@ -24,9 +24,9 @@
 use rustc::plugin::Registry;
 
 #[macro_export]
-macro_rules! exported_macro (() => (2i));
+macro_rules! exported_macro { () => (2i) }
 
-macro_rules! unexported_macro (() => (3i));
+macro_rules! unexported_macro { () => (3i) }
 
 #[plugin_registrar]
 pub fn plugin_registrar(reg: &mut Registry) {
index 9b4b1ceb5c1e7b072ad0d7c9cfeed48f14169365..84e944f69b98ee406dfec98baea4aaf10a1db92d 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 pub mod inner {
     #[macro_export]
-    macro_rules! foo(
+    macro_rules! foo {
         () => (1)
-    );
+    }
 }
diff --git a/src/test/auxiliary/macro_non_reexport_2.rs b/src/test/auxiliary/macro_non_reexport_2.rs
new file mode 100644 (file)
index 0000000..910fcd2
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+#![crate_type = "dylib"]
+
+// Since we load a serialized macro with all its attributes, accidentally
+// re-exporting a `#[macro_export] macro_rules!` is something of a concern!
+//
+// We avoid it at the moment only because of the order in which we do things.
+
+#[macro_use] #[no_link]
+extern crate macro_reexport_1;
diff --git a/src/test/auxiliary/macro_reexport_1.rs b/src/test/auxiliary/macro_reexport_1.rs
new file mode 100644 (file)
index 0000000..a913749
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 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.
+
+#![crate_type = "dylib"]
+#[macro_export]
+macro_rules! reexported {
+    () => ( 3u )
+}
diff --git a/src/test/auxiliary/macro_reexport_2.rs b/src/test/auxiliary/macro_reexport_2.rs
new file mode 100644 (file)
index 0000000..15d9f9c
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 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.
+
+#![crate_type = "dylib"]
+
+#[macro_reexport(reexported)]
+#[macro_use] #[no_link]
+extern crate macro_reexport_1;
diff --git a/src/test/auxiliary/macro_reexport_2_no_use.rs b/src/test/auxiliary/macro_reexport_2_no_use.rs
new file mode 100644 (file)
index 0000000..63142b0
--- /dev/null
@@ -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.
+
+#![crate_type = "dylib"]
+
+#[macro_reexport(reexported)]
+#[no_link]
+extern crate macro_reexport_1;
diff --git a/src/test/auxiliary/plugin_args.rs b/src/test/auxiliary/plugin_args.rs
new file mode 100644 (file)
index 0000000..b90c3f1
--- /dev/null
@@ -0,0 +1,50 @@
+// 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.
+
+// force-host
+
+#![feature(plugin_registrar)]
+
+extern crate syntax;
+extern crate rustc;
+
+use std::borrow::ToOwned;
+use syntax::ast;
+use syntax::codemap::Span;
+use syntax::ext::build::AstBuilder;
+use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacExpr, NormalTT};
+use syntax::parse::token;
+use syntax::print::pprust;
+use syntax::ptr::P;
+use rustc::plugin::Registry;
+
+struct Expander {
+    args: P<ast::MetaItem>,
+}
+
+impl TTMacroExpander for Expander {
+    fn expand<'cx>(&self,
+                   ecx: &'cx mut ExtCtxt,
+                   sp: Span,
+                   _: &[ast::TokenTree]) -> Box<MacResult+'cx> {
+
+        let attr = ecx.attribute(sp, self.args.clone());
+        let src = pprust::attribute_to_string(&attr);
+        let interned = token::intern_and_get_ident(src.as_slice());
+        MacExpr::new(ecx.expr_str(sp, interned))
+    }
+}
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    let args = reg.args().clone();
+    reg.register_syntax_extension(token::intern("plugin_args"),
+        NormalTT(box Expander { args: args, }, None));
+}
index c035f1203f8e3927e27a4c6d5c9cd436fb434509..12833daf6045854990ba64e416c6670832e64876 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index 614487c98171342a8cb4881f9ffc60139ad1be01..9e74bf281358faa1e582d81080183fb0fc38f392 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index 99506309a592e31a6aab080ac6db998636c7acd1..c900550041b5c82a58d243ce64e67c18a1cf72d4 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index 8ec4eaebbe8df974ced8614f2a46863bde7bc4b2..04f8eb3cf9bc0fd4121230931631fa66da136818 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index ad120e12f86fb92d2381a8ba3eec42c36e1a22b0..c7e0a18768a3d36ae7271d56bd00fd5bcd3ee9fb 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index c68c13c0991f2e7995a45c86d7ff806057ff677e..5100af323183b18726535987931245f269798ed0 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index 6c13e84a7febe933265e2448dee6c8e26b48f453..077c33cb90d756f3555b64c1aa81c2b1f4a7b2a0 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index 3d0973cb7ba1391d7f944656f5166d6feeb378b2..d481fa5a1fa3b033d65967408d0f13e7209e53d2 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index 1ad9e5e1c0e3a9186eafc2dd7796620a385db97c..9e99a355ac1ee2a17df3d10d77ed5bb798e93a6d 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index 6bd36b5a9b1c47839879bdc413c3746cc009e029..b8dd497ac99c8e6fae182d27dd29d4a40d0491df 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index c035f1203f8e3927e27a4c6d5c9cd436fb434509..12833daf6045854990ba64e416c6670832e64876 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index d67c8f4c181798ef84fa217709a2380a4f6ddef7..690ddc670f5fa57bb919d670d9bf31c4b1d45a33 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
index 73798f3787558ccef82259d69fd01f9a68d22243..216e8e997f22de643e86f712dd718888965dd7a1 100644 (file)
@@ -13,8 +13,6 @@
 //! should not affect the strict version hash (SVH) computation
 //! (#14132).
 
-#![feature(macro_rules)]
-
 #![crate_name = "a"]
 
 macro_rules! three {
diff --git a/src/test/auxiliary/two_macros.rs b/src/test/auxiliary/two_macros.rs
new file mode 100644 (file)
index 0000000..11b6108
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+// force-host
+
+#[macro_export]
+macro_rules! macro_one { () => ("one") }
+
+#[macro_export]
+macro_rules! macro_two { () => ("two") }
index 6a1f8588b60d74002f10cf696f5d4820c97c0a82..39462fdc1e528b8dfce72d33d0fd2d910a31caba 100644 (file)
 // it hasn't been defined just yet. Make sure we don't explode.
 
 #![no_std]
-#![feature(phase)]
 #![crate_type = "rlib"]
 
-#[phase(plugin, link)]
+#[macro_use]
 extern crate core;
 
 struct A;
index ee7c442da195c5a9b6a3cbc4f0e286aeebeeb706..9007b4fd64c43c440985a8da75774168e1ff27a4 100644 (file)
@@ -11,7 +11,6 @@
 // ignore-lexer-test FIXME #15679
 // Microbenchmarks for various functions in std and extra
 
-#![feature(macro_rules)]
 #![feature(unboxed_closures)]
 
 use std::io::File;
@@ -28,11 +27,12 @@ fn main() {
     let argv = os::args();
     let _tests = argv.slice(1, argv.len());
 
-    macro_rules! bench (
+    macro_rules! bench {
         ($id:ident) =>
             (maybe_run_test(argv.as_slice(),
                             stringify!($id).to_string(),
-                            $id)));
+                            $id))
+    }
 
     bench!(shift_push);
     bench!(read_line);
index 4e8e0d64d52cebdb169773ddafcaaa6d2e2cf598..16d6036d4c40ff8eb9b6d228941e37b088a41815 100644 (file)
@@ -38,7 +38,6 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#![feature(macro_rules)]
 #![feature(simd)]
 #![allow(experimental)]
 
index 4f87171f5d3fab49c1f20de70c6aabaac1f702b6..ef538eb699189e1d7cfd042ccc4fac62c625952d 100644 (file)
@@ -41,7 +41,7 @@
 // ignore-stage1
 // ignore-cross-compile #12102
 
-#![feature(macro_rules, phase, slicing_syntax)]
+#![feature(plugin, slicing_syntax)]
 
 extern crate regex;
 
diff --git a/src/test/compile-fail-fulldeps/gated-phase.rs b/src/test/compile-fail-fulldeps/gated-phase.rs
deleted file mode 100644 (file)
index 1f384b8..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 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.
-
-// aux-build:macro_crate_test.rs
-// ignore-stage1
-
-#[phase(plugin)]
-//~^ ERROR compile time crate loading is experimental and possibly buggy
-extern crate macro_crate_test;
-
-fn main() {}
diff --git a/src/test/compile-fail-fulldeps/gated-plugin.rs b/src/test/compile-fail-fulldeps/gated-plugin.rs
new file mode 100644 (file)
index 0000000..89090d5
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2013 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.
+
+// aux-build:macro_crate_test.rs
+// ignore-stage1
+
+#[plugin] #[no_link]
+//~^ ERROR compiler plugins are experimental and possibly buggy
+extern crate macro_crate_test;
+
+fn main() {}
index 5edaa78eeea38f184b09992def0bc34d766ae6bc..11ae55639596201edee9e5ead41537e9dc11c74d 100644 (file)
@@ -12,9 +12,9 @@
 // ignore-stage1
 // compile-flags: -D lint-me
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate lint_group_plugin_test;
 
 fn lintme() { } //~ ERROR item is named 'lintme'
index 9eb39a9178c027ffbaaf88499553ccd5e97a7b82..62007d6575a8db289fb27f98bf68d0db83601146 100644 (file)
 // aux-build:lint_plugin_test.rs
 // ignore-stage1
 
-#![feature(phase)]
+#![feature(plugin)]
 #![deny(test_lint)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate lint_plugin_test;
 
 fn lintme() { } //~ ERROR item is named 'lintme'
index 46aa4b6b5b74154b6990eef8a9114be14d35dbfb..da51c047f57e1109cbb2f2d9c65f4a576fdcee8c 100644 (file)
@@ -12,9 +12,9 @@
 // ignore-stage1
 // compile-flags: -D test-lint
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate lint_plugin_test;
 
 fn lintme() { } //~ ERROR item is named 'lintme'
index 329d3e86c052e0059ba28e07985c78012099e1ea..cf51958b53d8bec9304640e2cf4fd589675d6a7d 100644 (file)
 // aux-build:lint_plugin_test.rs
 // ignore-stage1
 
-#![feature(phase)]
+#![feature(plugin)]
 #![forbid(test_lint)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate lint_plugin_test;
 
 fn lintme() { } //~ ERROR item is named 'lintme'
index 601faa22d77a0a51945f0979e76cea0eb4069615..9a36143f65c6ad33e6a183faf953d864317126e2 100644 (file)
@@ -12,9 +12,9 @@
 // ignore-stage1
 // compile-flags: -F test-lint
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate lint_plugin_test;
 
 fn lintme() { } //~ ERROR item is named 'lintme'
index fc7664c480fdbf7969a1ab89e63f6f3b2f435d9c..46eb4d4b2eff1d7e8d116f209845128ab0fb63a6 100644 (file)
@@ -20,9 +20,9 @@
 // editors, so instead he made a macro that expands into the embedded
 // ident form.
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate macro_crate_test;
 
 fn main() {
diff --git a/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs b/src/test/compile-fail-fulldeps/macro-crate-doesnt-resolve.rs
new file mode 100644 (file)
index 0000000..adcdba0
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2013-2014 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.
+
+// aux-build:macro_crate_test.rs
+// ignore-stage1
+// ignore-android
+
+#[macro_use] #[no_link]
+extern crate macro_crate_test;
+
+fn main() {
+    macro_crate_test::foo();
+    //~^ ERROR failed to resolve. Use of undeclared type or module `macro_crate_test`
+    //~^^ ERROR unresolved name `macro_crate_test::foo`
+}
index d4f286f20e8f70d5f58f1bdf460fdd3055ea126f..1f44ac7cf9cae0f7604b30e8743a3242a8c6fb33 100644 (file)
@@ -14,8 +14,8 @@
 // ignore-android
 // ignore-cross-compile gives a different error message
 
-#![feature(phase)]
-#[phase(plugin)] extern crate rlib_crate_test;
+#![feature(plugin)]
+#[plugin] #[no_link] extern crate rlib_crate_test;
 //~^ ERROR: plugin crate `rlib_crate_test` only found in rlib format, but must be available in dylib format
 
 fn main() {}
index 6a3b0b91ffe297ed9d24f03a8d685f687c0c344e..b5ff8b715563288616a5a0fc5637dd56e100cd13 100644 (file)
@@ -12,9 +12,7 @@
 // ignore-stage1
 // ignore-android
 
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
 extern crate macro_crate_test;
 
 fn main() {
index 7a7eac7b709250ab1d991ebb739e9efde6980575..65657eea1efb0e0b2871a80758bf80d21d0a9798 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
 extern crate doesnt_exist; //~ ERROR can't find crate
 
 fn main() {}
diff --git a/src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs b/src/test/compile-fail-fulldeps/phase-syntax-doesnt-resolve.rs
deleted file mode 100644 (file)
index 00aeb1c..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2013-2014 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.
-
-// aux-build:macro_crate_test.rs
-// ignore-stage1
-// ignore-android
-
-#![feature(phase)]
-
-#[phase(plugin)]
-extern crate macro_crate_test;
-
-fn main() {
-    macro_crate_test::foo();
-    //~^ ERROR failed to resolve. Use of undeclared type or module `macro_crate_test`
-    //~^^ ERROR unresolved name `macro_crate_test::foo`
-}
diff --git a/src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs b/src/test/compile-fail-fulldeps/plugin-MacroRulesTT.rs
new file mode 100644 (file)
index 0000000..cff2e5e
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 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.
+
+// aux-build:macro_crate_MacroRulesTT.rs
+// ignore-stage1
+// ignore-android
+// error-pattern: plugin tried to register a new MacroRulesTT
+
+#![feature(plugin)]
+
+#[plugin] #[no_link]
+extern crate macro_crate_MacroRulesTT;
+
+fn main() { }
index 1b8fb32a808dc7067b76b973ff56368daeedd2eb..5ebcdb20b19523d44c6ab7ae1638ec71cb0b8369 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 //
+// ignore-stage1 (#20184)
 // compile-flags: -C codegen-units=2
 // error-pattern: build without -C codegen-units for more exact errors
 
index b79f4507d4673876825707ae5ea2cc06e24eb993..dcbb25ba5a95f629e64253039afe0c62f1b18b73 100644 (file)
@@ -11,8 +11,6 @@
 // Test that the borrow checker prevents pointers to temporaries
 // with statement lifetimes from escaping.
 
-#![feature(macro_rules)]
-
 use std::ops::Drop;
 
 static mut FLAGS: u64 = 0;
index 0a004c101ee4f2f7d374c87b8d65f79a3fb1a58c..1814b1cd544ef8ee02a725543b2cd2d4c41e667d 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 static A: uint = { 1u; 2 };
 //~^ ERROR: blocks in constants are limited to items and tail expressions
 
diff --git a/src/test/compile-fail/deprecated-phase.rs b/src/test/compile-fail/deprecated-phase.rs
new file mode 100644 (file)
index 0000000..1401494
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 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.
+
+#[phase(blah)]
+//~^ ERROR #[phase] is deprecated
+extern crate foo;
+
+fn main() {}
diff --git a/src/test/compile-fail/empty-macro-use.rs b/src/test/compile-fail/empty-macro-use.rs
new file mode 100644 (file)
index 0000000..fbf6287
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use()]
+extern crate two_macros;
+
+pub fn main() {
+    macro_two!();  //~ ERROR macro undefined
+}
index 49a927b9879e491eb62c98b8f71aebd2f5c217c7..6f75181c31cbc4bc0712581f148200859f9a3465 100644 (file)
@@ -8,11 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(phase)]
 #![deny(dead_code)]
 #![allow(unreachable_code)]
 
-#[phase(link, plugin)] extern crate core;
+#[macro_use] extern crate core;
 
 
 fn foo() { //~ ERROR function is never used
diff --git a/src/test/compile-fail/gated-macro-rules.rs b/src/test/compile-fail/gated-macro-rules.rs
deleted file mode 100644 (file)
index ae2f03f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2013 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.
-
-macro_rules! foo(() => ());
-//~^ ERROR: macro definitions are not stable enough for use
-
-fn main() {}
index 0e87dc97c2631f8e0c7ffb6d20a3be14e282f4aa..dd6682a6f4282c0cbddef859aba64e5f01b260f2 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! foo {
     () => { break 'x; }
 }
index fe87e32459bb19eab3b36a75e6b15b8e27642faa..24194d7bbe9702a6a86b64e41c19ded5b42f506f 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! foo {
     ($e: expr) => { 'x: loop { $e } }
 }
index b5954ac99303b9d47b1b8be8a8e006a810c346be..4ff3bec3c64594eb49b8b4bf0aef9fe54e6f11ad 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! foo {
     () => { break 'x; }
 }
index 67fa56b13067726de332a24298dc7e089dce3697..174e8a2834f4ba9507f1865fb7183e7358992bd8 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! foo {
     ($e: expr) => { 'x: for _ in range(0,1) { $e } }
 }
index 88b6854bb1d2c3a59df2e43e03f082c2c0a99136..971f643c0fe91c319c5ab276458078b663c5e2c5 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 fn macros() {
     macro_rules! foo{
         ($p:pat, $e:expr, $b:block) => {{
index 22ac2eb1f7d5d9ac7af48c99ce32360bcaf3cf72..74835f4bf22cafce53576e85bfb0c108da852fa9 100644 (file)
@@ -8,13 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! recursive(
-      () => (
-                recursive!() //~ ERROR recursion limit reached while expanding the macro `recursive`
-              )
-      );
+macro_rules! recursive {
+    () => (recursive!()) //~ ERROR recursion limit reached while expanding the macro `recursive`
+}
 
 fn main() {
     recursive!()
index 36afc729de9590c3f498cc73bf751ea3eb15f97b..370a6228db6ac733358a97e8ee5df73b3cde769d 100644 (file)
@@ -13,8 +13,6 @@
 
 // error-pattern:
 
-#![feature(macro_rules)]
-
 macro_rules! foo{
     () => {{
         macro_rules! bar{() => (())}
index 300831b100773f0976fb6bf0dee16cdcbeaec0af..d4de4e177f02684e19d87b14ce1a8faaf7def19b 100644 (file)
@@ -15,9 +15,7 @@
 
 // ignore-test
 
-#![feature(macro_rules)]
-
-macro_rules! f(() => (n))
+macro_rules! f { () => (n) }
 
 fn main() -> (){
     for n in range(0i, 1) {
index 5adcd7c2bb6d7b219f514468b3cb6a6f25bfa1a2..68ac19b383f5a06eeb6e09f5af834de762c5ff75 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! prob1 {
     (0) => {
         0
index 3222b2cd53719a60f4c667f63745ad76aaeee9fd..c5be0da5f4b2a2b6d866d5931901281d008bcfda 100644 (file)
@@ -8,15 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 // error-pattern: unexpected token
 
-macro_rules! e(
+macro_rules! e {
     ($inp:ident) => (
         $nonexistent
     );
-);
+}
 
 fn main() {
     e!(foo);
index 6d59f2c650184013e3b1076fbd618abdb4b6db65..0e24269ec444905b96e3e335efe2348b37822ce5 100644 (file)
 // aux-build:stability_cfg1.rs
 // aux-build:stability_cfg2.rs
 
-#![feature(phase)]
 #![deny(unstable)]
 #![deny(deprecated)]
 #![deny(experimental)]
 #![allow(dead_code)]
 
+#[macro_use]
+extern crate lint_stability; //~ ERROR: use of unmarked item
+
 mod cross_crate {
     extern crate stability_cfg1;
     extern crate stability_cfg2; //~ ERROR: use of experimental item
 
-    #[phase(plugin, link)]
-    extern crate lint_stability; //~ ERROR: use of unmarked item
-    use self::lint_stability::*;
+    use lint_stability::*;
 
     fn test() {
         let foo = MethodTester;
index 8899d06804f1e88442f7f6bc45195b5dbbaf4f52..56d2b2cd6c0845c8a2b4e1ca0df6e6e95ddb853f 100644 (file)
@@ -11,8 +11,6 @@
 #![allow(unused_unsafe)]
 #![allow(dead_code)]
 #![deny(unsafe_blocks)]
-#![feature(macro_rules)]
-
 unsafe fn allowed() {}
 
 #[allow(unsafe_blocks)] fn also_allowed() { unsafe {} }
index e92faa6bdaf6e902ca6b189dc86e12ed17c0ec8d..9cfffb5fa6b629941c6ba29045a2408825d2bfbb 100644 (file)
@@ -10,9 +10,7 @@
 //
 // regression test for #8005
 
-#![feature(macro_rules)]
-
-macro_rules! test ( () => { fn foo() -> int { 1i; } } );
+macro_rules! test { () => { fn foo() -> int { 1i; } } }
                                              //~^ ERROR not all control paths return a value
                                              //~^^ HELP consider removing this semicolon
 
diff --git a/src/test/compile-fail/macro-crate-nonterminal-non-root.rs b/src/test/compile-fail/macro-crate-nonterminal-non-root.rs
new file mode 100644 (file)
index 0000000..67aaf05
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:macro_crate_nonterminal.rs
+// ignore-stage1
+
+mod foo {
+    #[macro_use]
+    extern crate macro_crate_nonterminal;  //~ ERROR must be at the crate root
+}
+
+fn main() {
+}
index 71b656d0bbb57bb7796a42a8288e40a6cf27e0b1..53b29ccb0c0c7580b48be88f1ff096e0795fd921 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! ignored_item {
     () => {
         fn foo() {}
index f64b7be50e30781e55c76ed2fb6fe5878d40a9ca..e4fc5bb462700d0d8409e534488bc6e139bd98ba 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! test ( ($nm:ident,
+macro_rules! test { ($nm:ident,
                      #[$a:meta],
-                     $i:item) => (mod $nm { #![$a] $i }); );
+                     $i:item) => (mod $nm { #![$a] $i }); }
 
 test!(a,
       #[cfg(qux)],
diff --git a/src/test/compile-fail/macro-keyword.rs b/src/test/compile-fail/macro-keyword.rs
new file mode 100644 (file)
index 0000000..9d4ec9c
--- /dev/null
@@ -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 macro() {  //~ ERROR `macro` is a reserved keyword
+}
+
+pub fn main() {
+}
index 150187aa07d3c375820996f318fdd886d934063b..a66b63870143614aa407a27ce56eaab6688d4fd2 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! test ( ($a, $b) => (()); ); //~ ERROR Cannot transcribe
+macro_rules! test { ($a, $b) => (()); } //~ ERROR Cannot transcribe
 
 fn main() {
     test!()
diff --git a/src/test/compile-fail/macro-no-implicit-reexport.rs b/src/test/compile-fail/macro-no-implicit-reexport.rs
new file mode 100644 (file)
index 0000000..4a427f1
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:macro_reexport_1.rs
+// aux-build:macro_non_reexport_2.rs
+// ignore-stage1
+
+#[macro_use] #[no_link]
+extern crate macro_non_reexport_2;
+
+fn main() {
+    assert_eq!(reexported!(), 3u);  //~ ERROR macro undefined
+}
index 6d59c203d14bd34bcba66fa703766ee319175457..a0f23c72bc41e0b590f03d55081fb4a3d5b6b27e 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! test ( ($nm:ident,
+macro_rules! test { ($nm:ident,
                      #[$a:meta],
-                     $i:item) => (mod $nm { #[$a] $i }); );
+                     $i:item) => (mod $nm { #[$a] $i }); }
 
 test!(a,
       #[cfg(qux)],
diff --git a/src/test/compile-fail/macro-reexport-malformed-1.rs b/src/test/compile-fail/macro-reexport-malformed-1.rs
new file mode 100644 (file)
index 0000000..b9f754b
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 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.
+
+#[macro_reexport]  //~ ERROR bad macro reexport
+extern crate std;
+
+fn main() { }
diff --git a/src/test/compile-fail/macro-reexport-malformed-2.rs b/src/test/compile-fail/macro-reexport-malformed-2.rs
new file mode 100644 (file)
index 0000000..9ced5be
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 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.
+
+#[macro_reexport="foo"]  //~ ERROR bad macro reexport
+extern crate std;
+
+fn main() { }
diff --git a/src/test/compile-fail/macro-reexport-malformed-3.rs b/src/test/compile-fail/macro-reexport-malformed-3.rs
new file mode 100644 (file)
index 0000000..c8bd0a0
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 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.
+
+#[macro_reexport(foo="bar")]  //~ ERROR bad macro reexport
+extern crate std;
+
+fn main() { }
diff --git a/src/test/compile-fail/macro-reexport-not-locally-visible.rs b/src/test/compile-fail/macro-reexport-not-locally-visible.rs
new file mode 100644 (file)
index 0000000..c8e59f9
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:macro_reexport_1.rs
+// ignore-stage1
+
+#[macro_reexport(reexported)]
+#[no_link]
+extern crate macro_reexport_1;
+
+fn main() {
+    assert_eq!(reexported!(), 3u);  //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/macro-use-bad-args-1.rs b/src/test/compile-fail/macro-use-bad-args-1.rs
new file mode 100644 (file)
index 0000000..a73c4ad
--- /dev/null
@@ -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.
+
+#[macro_use(foo(bar))]  //~ ERROR bad macro import
+extern crate std;
+
+fn main() {
+}
diff --git a/src/test/compile-fail/macro-use-bad-args-2.rs b/src/test/compile-fail/macro-use-bad-args-2.rs
new file mode 100644 (file)
index 0000000..31efe85
--- /dev/null
@@ -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.
+
+#[macro_use(foo="bar")]  //~ ERROR bad macro import
+extern crate std;
+
+fn main() {
+}
diff --git a/src/test/compile-fail/macro-use-wrong-name.rs b/src/test/compile-fail/macro-use-wrong-name.rs
new file mode 100644 (file)
index 0000000..4e0486f
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one)]
+extern crate two_macros;
+
+pub fn main() {
+    macro_two!();  //~ ERROR macro undefined
+}
index f1f31a99e970af3e7954e4390b0d7a0419e7b3f9..314292085dfe61ab5ca34a90aeb5cb134ab28c56 100644 (file)
@@ -12,4 +12,3 @@ macro_rules! foo()  //~ ERROR semicolon
 
 fn main() {
 }
-
index 747b4815ac2ae2b8d5fcc4a0b11e785d6b8c5170..f4740492651ae03e4cd15a1412f8d8a8887bfccd 100644 (file)
 
 // forbid-output: in expansion of
 
-#![feature(macro_rules)]
-
-macro_rules! make_method ( ($name:ident) => (
-    fn $name(&self) { }
-));
+macro_rules! make_method {
+    ($name:ident) => ( fn $name(&self) { } )
+}
 
 struct S;
 
diff --git a/src/test/compile-fail/missing-macro-use.rs b/src/test/compile-fail/missing-macro-use.rs
new file mode 100644 (file)
index 0000000..0153d71
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+extern crate two_macros;
+
+pub fn main() {
+    macro_two!();  //~ ERROR macro undefined
+}
diff --git a/src/test/compile-fail/module-macro_use-arguments.rs b/src/test/compile-fail/module-macro_use-arguments.rs
new file mode 100644 (file)
index 0000000..6d3038b
--- /dev/null
@@ -0,0 +1,16 @@
+// Copyright 2013-2014 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.
+
+#[macro_use(foo, bar)] //~ ERROR arguments to macro_use are not allowed here
+mod foo {
+}
+
+fn main() {
+}
diff --git a/src/test/compile-fail/multi-plugin-attr.rs b/src/test/compile-fail/multi-plugin-attr.rs
new file mode 100644 (file)
index 0000000..1d98cd2
--- /dev/null
@@ -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.
+
+#[plugin]
+#[plugin]  //~ ERROR #[plugin] specified multiple times
+extern crate std;
+
+fn main() {}
diff --git a/src/test/compile-fail/no-link.rs b/src/test/compile-fail/no-link.rs
new file mode 100644 (file)
index 0000000..a9c2b6a
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+#[no_link]
+extern crate libc;
+
+fn main() {
+    unsafe {
+        libc::abs(0);  //~ ERROR Use of undeclared type or module `libc`
+                      //~^ ERROR unresolved name `libc::abs`
+    }
+}
index 3322fecf950c1437c9648f5c4d88fba9293793eb..1c79c9a2293a0f03bfbe9a63d151a265ab6bdb34 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! foo ( () => ( x ) );
+macro_rules! foo { () => ( x ) }
 
 fn main() {
     let foo!() = 2;
index de0d5c90fdd4b9ab4d547c42ad83f295e58a9f91..6e1ecb10e3a2ad1c46af841761b029522fb7cb35 100644 (file)
@@ -12,7 +12,6 @@
 // deeply nested types that will fail the `Send` check by overflow
 // when the recursion limit is set very low.
 
-#![feature(macro_rules)]
 #![allow(dead_code)]
 #![recursion_limit="10"]
 
index 179fb11d5fe5b00408d70f09bd0846aff006af60..c839ade75cf29875bc0b835b10477c0baeb22129 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-change-lit.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
 //~^ NOTE: perhaps this crate needs to be recompiled
index 1f65f3873a94d062dab936c81dac10c568b5bc56..df0adf36ce2e6f4fb72fe61aee610ceac7c2a8e0 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-change-significant-cfg.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
 //~^ NOTE: perhaps this crate needs to be recompiled
index 4e4f7b232f4693ad988c79922ae0dd47144bf64d..4774384fecd496558f6b282dfb8c8c6715075317 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-change-trait-bound.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
 //~^ NOTE: perhaps this crate needs to be recompiled
index 77b0a9211cafd4e1f1c16eca78b2f39991c98ffe..51d3fd0a73a129401789e3dafded5ebeaca7dd34 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-change-type-arg.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
 //~^ NOTE: perhaps this crate needs to be recompiled
index 13dcfa3b5da585eb4873ca821e30658a912d70a2..609e0f3689e5dfe6e2738771571b8241fd86149b 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-change-type-ret.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
 //~^ NOTE: perhaps this crate needs to be recompiled
index 7d26bdd15fb283d6a7f5872739931d443739d720..c42714609b6f8908f07d258d5e4b0b6b6e777805 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-change-type-static.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b; //~ ERROR: found possibly newer version of crate `a` which `b` depends on
 //~^ NOTE: perhaps this crate needs to be recompiled
index 8e0000246757d9a9a75c5eac6dec97f4854feca3..95cb17c215b7bbca96848e3f8e644a6f2fb2ad48 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules, trace_macros)]
+#![feature(trace_macros)]
 
 fn main() {
     trace_macros!(); //~ ERROR trace_macros! accepts only `true` or `false`
index ccf3d2dd75076ab781cb5dbaf61293fc27300856..adb8ee6940d3b22f94d32da70faa3f6e56307086 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 fn macros() {
     macro_rules! foo{
         ($p:pat, $e:expr, $b:block) => {{
index be52ffff1b45e9aaba2df6274ea5240cfe740b80..2aa31969a46ad30fba375b2b4f5a9e98f23c8f98 100644 (file)
 // lldb-command:continue
 
 
-#![feature(macro_rules)]
 #![omit_gdb_pretty_printer_section]
 
 macro_rules! trivial {
index 35bd22880cef742dde2823838e252219c4497a6a..500305f597075a6048b1ebaaf9f70ef489fff19e 100644 (file)
@@ -1,7 +1,6 @@
-#![feature(phase)]
 #![no_std]
 #![feature(globs)]
-#[phase(plugin, link)]
+#[macro_use]
 extern crate "std" as std;
 #[prelude_import]
 use std::prelude::v1::*;
index e524a2432ac4ef1248601ad4c02f3e035734b336..fd7c3f8cc0e4b346713e2854ff1d97d8ea09402d 100644 (file)
@@ -10,8 +10,7 @@
 
 // error-pattern:whatever
 
-#![feature(phase)]
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
 use std::os;
 
 fn main() {
index 972c85e376e51075b8a6ac17d7aa9412be37ce8a..446ef6f97e2972cb5e25156ad11fbc075d586148 100644 (file)
@@ -10,8 +10,7 @@
 
 // error-pattern:whatever
 
-#![feature(phase)]
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
 use std::os;
 use std::thread::Thread;
 
index bddf9b5a7ea5970b414c6aba90b7854b694c0ffa..39ece8a464a6fe8c77600ca6f9eacab0cb27196b 100644 (file)
@@ -10,8 +10,7 @@
 
 // error-pattern:whatever
 
-#![feature(phase)]
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
 use std::os;
 
 fn main() {
index ab1cf96999dcee9c74db38ac5c8c6e44bc29a9aa..11e042c8c4a067da2747cf79f23418486b78b420 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(phase)]
-
-#[phase(plugin, link)]
+#[macro_use]
 extern crate foo;
 
 fn main() {
index 2028710cbd2bc49f230aeb5897d9c06fe56743a9..a38b2cfb9628772d560e5b4703d021578b196551 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(phase)]
-
 extern crate lib;
-#[phase(plugin, link)] extern crate log;
+#[macro_use] extern crate log;
 
 fn main() {}
index bf60784ab58b9e1f748a3a8aa050d9cf43fb573e..6febe2ff7c1d324c76239c574a68c0b4a3fdb46c 100755 (executable)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
 // minimal junk
 #![no_std]
 
index c9d603c2e1cfbf180b442b2bc4c6a70a1d4587da..c31b67b8043ae400303e47c2a336e1db328231e5 100755 (executable)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
 // minimal junk
 #![no_std]
 
index 08c9f8b4aa7d52c9cf5e5cfb31d9ef11de6f2bb2..11e7da770291a309e45b0d675bc92a1e237a80a8 100644 (file)
@@ -11,9 +11,9 @@
 // ignore-stage1
 // ignore-android
 // aux-build:issue_16723_multiple_items_syntax_ext.rs
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)] extern crate issue_16723_multiple_items_syntax_ext;
+#[plugin] #[no_link] extern crate issue_16723_multiple_items_syntax_ext;
 
 multiple_items!();
 
index 726670b5d7f93c76ae6677fb79090a95c20fabe9..7615b25f9e40cacab27a0915db68c4ca523800ce 100644 (file)
@@ -12,9 +12,9 @@
 // ignore-stage1
 // ignore-pretty
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate lint_group_plugin_test;
 
 fn lintme() { } //~ WARNING item is named 'lintme'
index d3d1f1ea565a38580a8f7cb8082050f7870d1d59..7144d2b0f1e7162ac22652f586b82f78ad6bcba0 100644 (file)
@@ -12,9 +12,9 @@
 // ignore-stage1
 // compile-flags: -A test-lint
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate lint_plugin_test;
 
 fn lintme() { }
index 8c5269e2274108e66f6e39146858b152e2d10ea8..d11242f4fe643e92f07282bc0b898bf7a52b1c82 100644 (file)
@@ -12,9 +12,9 @@
 // ignore-stage1
 // ignore-pretty
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate lint_plugin_test;
 
 fn lintme() { } //~ WARNING item is named 'lintme'
index 0afd76e1659c48aefe9aac85d1950ea8fc9fa837..a8762234ad996db102285f217f5ec591b8c7f9b6 100644 (file)
@@ -14,9 +14,9 @@
 // Issue #15750: a macro that internally parses its input and then
 // uses `quote_expr!` to rearrange it should be hygiene-preserving.
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate macro_crate_test;
 
 fn main() {
index dd585ea979408ec30e1abd46f9a4960296439bf1..d943cf0457b4feace6006a53515159ba934fa64e 100644 (file)
@@ -11,9 +11,9 @@
 // aux-build:plugin_crate_outlive_expansion_phase.rs
 // ignore-stage1
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate plugin_crate_outlive_expansion_phase;
 
 pub fn main() {}
index 0f5e2cb3b6b460322c0f1570cf807c7c93ad39dc..4ffb8a3f74d4f0769bd368dc443ab267d595fd9b 100644 (file)
@@ -11,9 +11,9 @@
 // aux-build:macro_crate_test.rs
 // ignore-stage1
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[macro_use] #[plugin] #[no_link]
 extern crate macro_crate_test;
 
 #[into_foo]
diff --git a/src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs b/src/test/run-pass-fulldeps/phase-syntax-link-does-resolve.rs
deleted file mode 100644 (file)
index 47ff7d3..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013-2014 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.
-
-// aux-build:macro_crate_test.rs
-// ignore-stage1
-// ignore-cross-compile
-//
-// macro_crate_test will not compile on a cross-compiled target because
-// libsyntax is not compiled for it.
-
-#![feature(phase)]
-
-#[phase(plugin, link)]
-extern crate macro_crate_test;
-
-fn main() {
-    assert_eq!(1, make_a_1!());
-    macro_crate_test::foo();
-}
diff --git a/src/test/run-pass-fulldeps/plugin-link-does-resolve.rs b/src/test/run-pass-fulldeps/plugin-link-does-resolve.rs
new file mode 100644 (file)
index 0000000..518d02e
--- /dev/null
@@ -0,0 +1,26 @@
+// Copyright 2013-2014 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.
+
+// aux-build:macro_crate_test.rs
+// ignore-stage1
+// ignore-cross-compile
+//
+// macro_crate_test will not compile on a cross-compiled target because
+// libsyntax is not compiled for it.
+
+#![feature(plugin)]
+
+#[plugin]
+extern crate macro_crate_test;
+
+fn main() {
+    assert_eq!(1, make_a_1!());
+    macro_crate_test::foo();
+}
index 73a4a51f31c4e6887ff6ca90d13b76427c44e7b3..d76766094ed773d40974da44a142b0ff8b728116 100644 (file)
@@ -11,9 +11,9 @@
 // aux-build:roman_numerals.rs
 // ignore-stage1
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate roman_numerals;
 
 pub fn main() {
index b3fae671c52660dff6f1a902f11d78234334f2eb..1c74c8ad08eec0bb64bfbbc338853b7f9bdb7d97 100644 (file)
@@ -12,9 +12,9 @@
 // aux-build:syntax-extension-with-dll-deps-2.rs
 // ignore-stage1
 
-#![feature(phase)]
+#![feature(plugin)]
 
-#[phase(plugin)]
+#[plugin] #[no_link]
 extern crate "syntax-extension-with-dll-deps-2" as extension;
 
 fn main() {
index 822db63971e21b6ef3b6697ccee622c6c8b2956b..28db3953a0021d2834c2c1efa3234f1120ea121c 100644 (file)
@@ -11,8 +11,6 @@
 // Check that we do not ICE when compiling this
 // macro, which reuses the expression `$id`
 
-#![feature(macro_rules)]
-
 
 struct Foo {
   a: int
@@ -24,12 +22,12 @@ pub enum Bar {
 
 impl Foo {
   fn elaborate_stm(&mut self, s: Box<Bar>) -> Box<Bar> {
-    macro_rules! declare(
+    macro_rules! declare {
       ($id:expr, $rest:expr) => ({
         self.check_id($id);
         box Bar::Bar2($id, $rest)
       })
-    );
+    }
     match s {
       box Bar::Bar2(id, rest) => declare!(id, self.elaborate_stm(rest)),
       _ => panic!()
index 3f6d6a02c79264d3d751a8fcf62d5ab1d1d06f61..e3e004105076244cb945a09ffdb4aa86a249212d 100644 (file)
@@ -11,9 +11,7 @@
 // ignore-android (FIXME #11419)
 // exec-env:RUST_LOG=info
 
-#![feature(phase)]
-
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 use log::{set_logger, Logger, LogRecord};
index ec9ef3815013697c7f45fcc08ad2450e73ac703a..aeb6fcbbc0f01fb63f9e28a03aa29606eec6b74f 100644 (file)
 // check that cfg correctly chooses between the macro impls (see also
 // cfg-macros-notfoo.rs)
 
-#![feature(macro_rules)]
-
 #[cfg(foo)]
-#[macro_escape]
+#[macro_use]
 mod foo {
     macro_rules! bar {
         () => { true }
@@ -24,7 +22,7 @@ macro_rules! bar {
 }
 
 #[cfg(not(foo))]
-#[macro_escape]
+#[macro_use]
 mod foo {
     macro_rules! bar {
         () => { false }
index fb44176ec2212c347b89f50efe80f5af17d77f00..adc27d556227e3fb22b3bf10e4c1216f53b50c72 100644 (file)
 // check that cfg correctly chooses between the macro impls (see also
 // cfg-macros-foo.rs)
 
-#![feature(macro_rules)]
-
 #[cfg(foo)]
-#[macro_escape]
+#[macro_use]
 mod foo {
     macro_rules! bar {
         () => { true }
@@ -24,7 +22,7 @@ macro_rules! bar {
 }
 
 #[cfg(not(foo))]
-#[macro_escape]
+#[macro_use]
 mod foo {
     macro_rules! bar {
         () => { false }
index 932a5a044ad3e2bfda211090ac662ec64734ab7b..8969cca2610ea65f1461364b66ad6f593a7adcf0 100644 (file)
@@ -11,8 +11,6 @@
 // Test that the lifetime of rvalues in for loops is extended
 // to the for loop itself.
 
-#![feature(macro_rules)]
-
 use std::ops::Drop;
 
 static mut FLAGS: u64 = 0;
index 42f6914e081a300df8154689b8dcebd916d6bf2b..59763e417a2585233030bad588bddd738472c98b 100644 (file)
@@ -12,8 +12,6 @@
 // statement or end of block, as appropriate given the temporary
 // lifetime rules.
 
-#![feature(macro_rules)]
-
 use std::ops::Drop;
 
 static mut FLAGS: u64 = 0;
@@ -61,7 +59,7 @@ fn drop(&mut self) {
     }
 }
 
-macro_rules! end_of_block(
+macro_rules! end_of_block {
     ($pat:pat, $expr:expr) => (
         {
             println!("end_of_block({})", stringify!({let $pat = $expr;}));
@@ -74,9 +72,9 @@ macro_rules! end_of_block(
             check_flags(1);
         }
     )
-);
+}
 
-macro_rules! end_of_stmt(
+macro_rules! end_of_stmt {
     ($pat:pat, $expr:expr) => (
         {
             println!("end_of_stmt({})", stringify!($expr));
@@ -91,7 +89,7 @@ macro_rules! end_of_stmt(
             check_flags(0);
         }
     )
-);
+}
 
 pub fn main() {
 
index d2caecdf05be2a31a8d81282b88c02182bc737c7..ca7f761b80d3111ecf485d39c56a26675f75ecf4 100644 (file)
@@ -11,8 +11,6 @@
 // no-pretty-expanded
 
 #![allow(unused_must_use, dead_code, deprecated)]
-#![feature(macro_rules)]
-
 use std::io::MemWriter;
 use std::fmt;
 
index f87d92dc16f7f22933cbf31d2d0c0880e3625912..e3bdbeb169295e7a8d9236af7726f6da72b95af1 100644 (file)
@@ -11,8 +11,7 @@
 // compile-flags: --cfg ndebug
 // exec-env:RUST_LOG=conditional-debug-macro-off=4
 
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 pub fn main() {
index cac805189b82e796e9c58271545d036050f8fee3..11590ceb19d4889960e84669a22b9a51608094fb 100644 (file)
@@ -8,16 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! assert_approx_eq(
+macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
         use std::num::Float;
         let (a, b) = (&$a, &$b);
         assert!((*a - *b).abs() < 1.0e-6,
                 "{} is not approximately equal to {}", *a, *b);
     })
-);
+}
 
 static A: int = -4 + 3;
 static A2: uint = 3 + 3;
index 09f26b15734ff22a49a3cd9f09c65b16164b95b9..03afe798954d514afe053882edf4b35b0028c0cb 100644 (file)
@@ -11,8 +11,6 @@
 // General test that function items in static blocks
 // can be generated with a macro.
 
-#![feature(macro_rules)]
-
 struct MyType {
     desc: &'static str,
     data: uint,
index 3365f09cd80ab901ab56d8320519bee71921707b..d55b420db083e28f882e112cbb4d4643a3ef1092 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 mod foo {
     pub trait Value {
         fn value(&self) -> uint;
index c1db8a6eb13f4f27a39e0504b69f89cb2b893608..3298976de6ce34d8bd6f13fe8af4d629b951f1fe 100644 (file)
@@ -15,7 +15,6 @@
 // memory, which makes for some *confusing* logs. That's why these are here
 // instead of in std.
 
-#![feature(macro_rules)]
 #![reexport_test_harness_main = "test_main"]
 
 extern crate libc;
@@ -26,9 +25,9 @@
 use std::sync::mpsc::channel;
 use std::thread::Thread;
 
-macro_rules! succeed( ($e:expr) => (
+macro_rules! succeed { ($e:expr) => (
     match $e { Ok(..) => {}, Err(e) => panic!("panic: {}", e) }
-) );
+) }
 
 fn test_destroy_once() {
     let mut p = sleeper();
diff --git a/src/test/run-pass/crate-leading-sep.rs b/src/test/run-pass/crate-leading-sep.rs
new file mode 100644 (file)
index 0000000..b2956f4
--- /dev/null
@@ -0,0 +1,14 @@
+// Copyright 2014 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() {
+    use ::std::mem;
+    mem::drop(2u);
+}
diff --git a/src/test/run-pass/deprecated-macro_escape-inner.rs b/src/test/run-pass/deprecated-macro_escape-inner.rs
new file mode 100644 (file)
index 0000000..7960a91
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright 2013-2014 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.
+
+// ignore-pretty
+
+mod foo {
+    #![macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use
+    //~^ HELP consider an outer attribute
+}
+
+fn main() {
+}
diff --git a/src/test/run-pass/deprecated-macro_escape.rs b/src/test/run-pass/deprecated-macro_escape.rs
new file mode 100644 (file)
index 0000000..b03905e
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2013-2014 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.
+
+// ignore-pretty
+
+#[macro_escape] //~ WARNING macro_escape is a deprecated synonym for macro_use
+mod foo {
+}
+
+fn main() {
+}
diff --git a/src/test/run-pass/deprecated-phase-syntax.rs b/src/test/run-pass/deprecated-phase-syntax.rs
deleted file mode 100644 (file)
index df835da..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2013-2014 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.
-
-#![feature(phase)]
-
-//~ WARNING phase(syntax) is a deprecated synonym for phase(plugin)
-#[phase(syntax, link)]
-extern crate log;
-
-fn main() {
-    debug!("foo");
-}
index 97f6ee341a71f7b4a0506d29703f79d0a4188e8a..c9b60d22ecb7b9bd7a6e6a8cbd3172b198be353e 100644 (file)
@@ -8,16 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! define_vec (
+macro_rules! define_vec {
     () => (
         mod foo {
             #[derive(PartialEq)]
             pub struct bar;
         }
     )
-);
+}
 
 define_vec!();
 
index f619c824d5e68d805e06d49b062a33514f795ee6..e8086b8b7c6b20c2a988de3cd5976fa32160c03c 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 #[derive(Show)]
 struct Unit;
 
index 73abec89a2df9cebedc408d01b93e5702ccb2dda..07941eca2243ec4cb8107bdf177b8489c1c2fc5c 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! check {
     ($m:ident, $t:ty, $v:expr) => {{
         mod $m {
index 38d1093762432652df59625ee5e8fddebe155a7d..1fb434f7d76192332c667e6747fa6c317e634563 100644 (file)
@@ -8,14 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 use std::num::strconv::ExponentFormat::{ExpBin, ExpDec};
 use std::num::strconv::SignificantDigits::DigMax;
 use std::num::strconv::SignFormat::{SignAll, SignNeg};
 use std::num::strconv::float_to_str_common as to_string;
 
-macro_rules! t(($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()); } });
+macro_rules! t {
+    ($a:expr, $b:expr) => { { let (r, _) = $a; assert_eq!(r, $b.to_string()); } }
+}
 
 pub fn main() {
     // Basic usage
index 0d56f28e8fae7afc639625a4f3ab6fc9fea4cc7c..fbaeb1753f41de6436f2c376b6b401c9672e38b0 100644 (file)
@@ -10,8 +10,6 @@
 
 // A test of the macro system. Can we do HTML literals?
 
-#![feature(macro_rules)]
-
 
 /*
 
 */
 use HTMLFragment::{tag, text};
 
-macro_rules! html (
+macro_rules! html {
     ( $($body:tt)* ) => (
         parse_node!( []; []; $($body)* )
     )
-);
+}
 
-macro_rules! parse_node (
+macro_rules! parse_node {
     (
         [:$head:ident ($(:$head_nodes:expr),*)
          $(:$tags:ident ($(:$tag_nodes:expr),*))*];
@@ -85,7 +83,7 @@ macro_rules! parse_node (
     );
 
     ( []; [:$e:expr]; ) => ( $e );
-);
+}
 
 pub fn main() {
     let _page = html! (
index 397ce75b6b93e91b53ea5d33246d93928994b1f4..17c0299cf4dd7aaf8d6c73579a5b907891f789dd 100644 (file)
@@ -10,8 +10,6 @@
 
 // ignore-pretty: pprust doesn't print hygiene output
 
-#![feature(macro_rules)]
-
 macro_rules! loop_x {
     ($e: expr) => {
         // $e shouldn't be able to interact with this 'x
index 53c081ff83e0e906b354731a5b75cdd8706f47d7..e899a1adb794f1a5e72b4b543f451c3908b88819 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! loop_x {
     ($e: expr) => {
         // $e shouldn't be able to interact with this 'x
index 1efae89f665631ad0f0ac47a6b5422e69beb5573..d38b0ea27476569f1f8ac0df6e1cb7776c03e3cb 100644 (file)
@@ -11,7 +11,6 @@
 // no-pretty-expanded unnecessary unsafe block generated
 // ignore-lexer-test FIXME #15679
 
-#![feature(macro_rules)]
 #![deny(warnings)]
 #![allow(unused_must_use)]
 
@@ -37,7 +36,9 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-macro_rules! t(($a:expr, $b:expr) => { assert_eq!($a.as_slice(), $b) });
+macro_rules! t {
+    ($a:expr, $b:expr) => { assert_eq!($a.as_slice(), $b) }
+}
 
 pub fn main() {
     // Various edge cases without formats
index 523e7ab02d4a3481228a1d663a428d250118b660..ed88b3c65e09c8f428c3740c77e693a0a9b82c2e 100644 (file)
@@ -9,16 +9,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules, intrinsics)]
+#![feature(intrinsics)]
 
-macro_rules! assert_approx_eq(
+macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
         use std::num::Float;
         let (a, b) = (&$a, &$b);
         assert!((*a - *b).abs() < 1.0e-6,
                 "{} is not approximately equal to {}", *a, *b);
     })
-);
+}
 
 mod rusti {
     extern "rust-intrinsic" {
index bac846dfa203bba803ae6af42be382d5cf0123ee..f983f233ee35680e8697439ab39d43e9fab1e40b 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(phase)]
-
-#[phase(plugin, link)] extern crate "std" as std2;
+#[macro_use] extern crate "std" as std2;
 
 fn main() {}
index 960dae8b7043ca4c58541e464a121040a2985928..a441729e2d0ba015287dad9217a5a823f59a9a4a 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(asm, macro_rules)]
+#![feature(asm)]
 
 type History = Vec<&'static str>;
 
index 01c96b7563a752acdc333d145f36f01b515ca5b0..6d1813f8aa437bb965aa254a31777c3467c64fc3 100644 (file)
@@ -10,9 +10,9 @@
 
 // ignore-pretty
 
-#![feature(macro_rules)]
-
-macro_rules! third(($e:expr)=>({let x = 2; $e[x]}));
+macro_rules! third {
+    ($e:expr) => ({let x = 2; $e[x]})
+}
 
 fn main() {
     let x = vec!(10u,11u,12u,13u);
index a11b34e4762759053d456564f6b2975581a71303..e3c102e01ec5e0cb0a2a3289befde1848167a3f9 100644 (file)
@@ -8,13 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! inner (
-    ($e:pat ) => ($e));
+macro_rules! inner {
+    ($e:pat ) => ($e)
+}
 
-macro_rules! outer (
-    ($e:pat ) => (inner!($e)));
+macro_rules! outer {
+    ($e:pat ) => (inner!($e))
+}
 
 fn main() {
     let outer!(g1) = 13i;
index 0cd25bc2c719b200cd4b9c591af41279231b5215..7c3b0a5f1f0146fbd413735612440b2c8056aa63 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! print_hd_tl (
+macro_rules! print_hd_tl {
     ($field_hd:ident, $($field_tl:ident),+) => ({
         print!("{}", stringify!($field_hd));
         print!("::[");
@@ -21,7 +19,7 @@ macro_rules! print_hd_tl (
         // FIXME: #9970
         print!("{}", "]\n");
     })
-);
+}
 
 pub fn main() {
     print_hd_tl!(x, y, z, w)
index 24dcc3838c5fc4c2f7d05a7cf22bafc28b8127ab..32fca7a182c1b7c465dfc2f915fa11cbb8912bd5 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 use std::default::Default;
 
 pub struct X<T> {
index f2167da31fc2bebea2cf860bb51e9133f9e86bdd..589ccefd9ea2801a2b6e7e6d6fb2049129037733 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 struct Element;
 
 macro_rules! foo {
index c69b66f4dbd76fe408102184898587a94df22530..86948ebcb91e0e4dbf2de046876376d3508a3f41 100644 (file)
@@ -14,8 +14,6 @@
 // with different mutability in macro in two methods
 
 #![allow(unused_variable)] // unused foobar_immut + foobar_mut
-#![feature(macro_rules)]
-
 trait FooBar {}
 struct Bar(i32);
 struct Foo { bar: Bar }
@@ -27,7 +25,7 @@ trait Test {
     fn get_mut(&mut self) -> &mut FooBar;
 }
 
-macro_rules! generate_test(($type_:path, $slf:ident, $field:expr) => (
+macro_rules! generate_test { ($type_:path, $slf:ident, $field:expr) => (
     impl Test for $type_ {
         fn get_immut(&$slf) -> &FooBar {
             &$field as &FooBar
@@ -37,7 +35,7 @@ fn get_mut(&mut $slf) -> &mut FooBar {
             &mut $field as &mut FooBar
         }
     }
-));
+)}
 
 generate_test!(Foo, self, self.bar);
 
index d4ea05004a064b99858ce7535f7bb6a83a28679b..865905bf50441a9143b527b7af53924cf8f20573 100644 (file)
@@ -8,15 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! sty(
+macro_rules! sty {
     ($t:ty) => (stringify!($t))
-);
+}
 
-macro_rules! spath(
+macro_rules! spath {
     ($t:path) => (stringify!($t))
-);
+}
 
 fn main() {
     assert_eq!(sty!(int), "int");
index 5826a5f9919f4a89542923ea15ba992e670161f9..b70711f9f39e25a393a5fafc2e59b3726e5ff92e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 // after fixing #9384 and implementing hygiene for match bindings,
 // this now fails because the insertion of the 'y' into the match
 // doesn't cause capture. Making this macro hygienic (as I've done)
@@ -20,7 +18,7 @@ enum T {
     B(uint)
 }
 
-macro_rules! test(
+macro_rules! test {
     ($id:ident, $e:expr) => (
         fn foo(t: T) -> int {
             match t {
@@ -29,7 +27,7 @@ fn foo(t: T) -> int {
             }
         }
     )
-);
+}
 
 test!(y, 10 + (y as int));
 
index 60011281d425e48c2405f943596476258873d424..09d0f20c96d6c4d9eda35e3fdb22a6daf2780b4e 100644 (file)
@@ -8,16 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! silly_macro(
+macro_rules! silly_macro {
     () => (
         pub mod Qux {
             pub struct Foo { x : u8 }
             pub fn bar(_foo : Foo) {}
         }
     );
-);
+}
 
 silly_macro!();
 
index 3ca060f45a5f50f031d9bedfa194b4644c2909e1..5d5240272e542df6e08ada88770da3f653922ffd 100644 (file)
@@ -10,8 +10,6 @@
 
 // ignore-pretty
 
-#![feature(macro_rules)]
-
 
 pub trait bomb { fn boom(&self, Ident); }
 pub struct S;
@@ -19,8 +17,8 @@ impl bomb for S { fn boom(&self, _: Ident) { } }
 
 pub struct Ident { name: uint }
 
-// macro_rules! int3( () => ( unsafe { asm!( "int3" ); } ) )
-macro_rules! int3( () => ( { } ) );
+// macro_rules! int3 { () => ( unsafe { asm!( "int3" ); } ) }
+macro_rules! int3 { () => ( { } ) }
 
 fn Ident_new() -> Ident {
     int3!();
index 1f385b2fb1589861a030333a97a6887bdb6768d9..e5a287d01491939f3818c3702b2d82632063c715 100644 (file)
@@ -10,9 +10,9 @@
 
 // ignore-test #9737
 
-#![feature(macro_rules)]
-
-macro_rules! f((v: $x:expr) => ( println!("{}", $x) ))
+macro_rules! f {
+    (v: $x:expr) => ( println!("{}", $x) )
+}
 
 fn main () {
     let v = 5;
index 5dfc4208554b1e5d280bf39a6109771270ba9ec3..a6060bebbc5cde4ec793ec374d0e54d73469ada4 100644 (file)
 
 // ignore-test #9383
 
-#![feature(macro_rules)]
-
 // shouldn't affect evaluation of $ex:
-macro_rules! bad_macro (($ex:expr) => ({(|_x| { $ex }) (9) }))
+macro_rules! bad_macro {
+    ($ex:expr) => ({(|_x| { $ex }) (9) })
+}
 
 fn takes_x(_x : int) {
     assert_eq!(bad_macro!(_x),8);
index 5eed791e0582ddd5acfde08fc019b8d2baf29319..2287cc48b66ce1e6504255e18347567c96fbc0f5 100644 (file)
@@ -8,10 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 // shouldn't affect evaluation of $ex:
-macro_rules! bad_macro (($ex:expr) => ({let _x = 9i; $ex}));
+macro_rules! bad_macro {
+    ($ex:expr) => ({let _x = 9i; $ex})
+}
+
 pub fn main() {
     let _x = 8i;
     assert_eq!(bad_macro!(_x),8i)
index 4b97d274fbae420f453df14d18fefd9ef127fcb3..262d9b21eb48bddd57815f6d246e26151037ef4a 100644 (file)
@@ -11,8 +11,7 @@
 // compile-flags:--cfg ndebug
 // exec-env:RUST_LOG=logging-enabled-debug=debug
 
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 pub fn main() {
index c4f7b1492ab57e1c20903c8f964d8c7aa590a211..372cdc401b54929ee084e12cbf7bcb88a16caf89 100644 (file)
@@ -10,8 +10,7 @@
 
 // exec-env:RUST_LOG=logging-enabled=info
 
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 pub fn main() {
index ebbe7fa65cdf84dfc9d6a9e369b773dbfaf5d145..0f13df644a1f7760d69da0eefbc4901ffd259b52 100644 (file)
@@ -12,9 +12,7 @@
 // ignore-windows
 // exec-env:RUST_LOG=debug
 
-#![feature(phase)]
-
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 
 use std::io::Command;
index 7b4d376993aa93e5b1692000e7949bfedf251cff..80b2f408c1915674ad74da5987f5eb904bb59df5 100644 (file)
 
 // ignore-pretty - token trees can't pretty print
 
-#![feature(macro_rules)]
-
 pub fn main() {
 
-    macro_rules! mylambda_tt(
+    macro_rules! mylambda_tt {
         ($x:ident, $body:expr) => ({
             fn f($x: int) -> int { return $body; };
             f
         })
-    );
+    }
 
     assert!(mylambda_tt!(y, y * 2)(8) == 16);
 }
index 3c170634c2231eeabf7065494ceeb67a7d0a3434..60217139cd77804e60bc652b67b0de7552422ca2 100644 (file)
@@ -10,8 +10,6 @@
 
 // ignore-pretty - token trees can't pretty print
 
-#![feature(macro_rules)]
-
 macro_rules! descriptions {
     ($name:ident is $desc:expr) => {
         // Check that we will correctly expand attributes
index 4df3b94c1c9d1339917531a81a6d5ec8cc09a0f5..521aef4b5ba5b0b02bebe2e30381d75fc3d8c512 100644 (file)
@@ -10,8 +10,6 @@
 
 // ignore-pretty - token trees can't pretty print
 
-#![feature(macro_rules)]
-
 macro_rules! compiles_fine {
     (#[$at:meta]) => {
         // test that the different types of attributes work
index 8a9fbbe284864152ce23e57859f98668f37820c8..6c568d6d493ca9d2aa352280ea4a6f3ea5e21707 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! do_block{
     ($val:block) => {$val}
 }
index 70080fcc3c91dcf37392adffcbc3c0f53a1e4852..7505fa6e6841afbb37d63a03f2e7bc4866c86e89 100644 (file)
@@ -10,9 +10,7 @@
 
 // aux-build:macro_crate_def_only.rs
 
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
 extern crate macro_crate_def_only;
 
 pub fn main() {
diff --git a/src/test/run-pass/macro-crate-nonterminal-renamed.rs b/src/test/run-pass/macro-crate-nonterminal-renamed.rs
new file mode 100644 (file)
index 0000000..cb91929
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 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.
+
+// aux-build:macro_crate_nonterminal.rs
+// ignore-stage1
+
+#[macro_use]
+extern crate "macro_crate_nonterminal" as new_name;
+
+pub fn main() {
+    new_name::check_local();
+    assert_eq!(increment!(5), 6);
+}
diff --git a/src/test/run-pass/macro-crate-nonterminal.rs b/src/test/run-pass/macro-crate-nonterminal.rs
new file mode 100644 (file)
index 0000000..9882f80
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 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.
+
+// aux-build:macro_crate_nonterminal.rs
+// ignore-stage1
+
+#[macro_use]
+extern crate macro_crate_nonterminal;
+
+pub fn main() {
+    macro_crate_nonterminal::check_local();
+    assert_eq!(increment!(5), 6);
+}
diff --git a/src/test/run-pass/macro-crate-use.rs b/src/test/run-pass/macro-crate-use.rs
new file mode 100644 (file)
index 0000000..fbbe010
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2014 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.
+
+pub fn increment(x: uint) -> uint {
+    x + 1
+}
+
+#[macro_export]
+macro_rules! increment {
+    ($x:expr) => ({
+        use $crate::increment;
+        increment($x)
+    })
+}
+
+fn main() {
+    assert_eq!(increment!(3), 4);
+}
index f85c6f1fc9349966947f518a45d38040a8162e83..c4012e2cf3c7e4459d30492642b5d0b879d5ce1e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! foo2 {
     () => {
         "foo"
index 88ca466b4afdf30c97ce8306913a58638b671c53..ef22410751c0c860045e2830ed4921c80a4b052a 100644 (file)
@@ -11,9 +11,7 @@
 //aux-build:macro_export_inner_module.rs
 //ignore-stage1
 
-#![feature(phase)]
-
-#[phase(plugin)]
+#[macro_use] #[no_link]
 extern crate macro_export_inner_module;
 
 pub fn main() {
index 45712f5c62a6e5efe94cce6a688ff4a376d833ca..ff5b29d6ac88b16f3c3fa294327972ce12314406 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! overly_complicated (
+macro_rules! overly_complicated {
     ($fnname:ident, $arg:ident, $ty:ty, $body:block, $val:expr, $pat:pat, $res:path) =>
     ({
         fn $fnname($arg: $ty) -> Option<$ty> $body
@@ -22,7 +20,7 @@ fn $fnname($arg: $ty) -> Option<$ty> $body
         }
     })
 
-);
+}
 
 pub fn main() {
     assert!(overly_complicated!(f, x, Option<uint>, { return Some(x); },
index ecd7c0458f701a391157fa7203b7ac80b5d8b631..ce748967498387ad24166e01167ee5b23f872074 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! four (
+macro_rules! four {
     () => (4)
-);
+}
 
 fn main() {
     let _x: [u16; four!()];
index 4b01fdf816216b35af8d264b6639208e832dc21d..47e3a0723993e2240f1fd499fd194d1758282efc 100644 (file)
@@ -11,8 +11,6 @@
 // ignore-pretty - token trees can't pretty print
 // compile-flags: --cfg foo
 
-#![feature(macro_rules)]
-
 macro_rules! compiles_fine {
     ($at:meta) => {
         #[cfg($at)]
index aa6de9acf6b88eac4493ae981f807d5815051456..fd16958d8964b9ab259951290d586acd97107c9c 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 struct A;
 
 macro_rules! make_thirteen_method {() => (fn thirteen(&self)->int {13})}
index 4fb130f0e1314584ed8d02702be0e1228ccd40a8..f78f93e84810c8108d130ff63af29ac72749917d 100644 (file)
@@ -10,9 +10,7 @@
 
 // ignore-pretty - token trees can't pretty print
 
-#![feature(macro_rules)]
-
-macro_rules! make_foo(
+macro_rules! make_foo {
     () => (
         struct Foo;
 
@@ -20,7 +18,7 @@ impl Foo {
             fn bar(&self) {}
         }
     )
-);
+}
 
 make_foo!();
 
index 9367a231d4f65d15f1fbe06927e25424eaefa118..c6efc2f2bc83bbbd1180c747490c68d1bab8255c 100644 (file)
@@ -8,17 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! list (
+macro_rules! list {
     ( ($($id:ident),*) ) => (());
     ( [$($id:ident),*] ) => (());
     ( {$($id:ident),*} ) => (());
-);
+}
 
-macro_rules! tt_list (
+macro_rules! tt_list {
     ( ($($tt:tt),*) ) => (());
-);
+}
 
 pub fn main() {
     list!( () );
index c47b5e1108901aab41c7dfe66ed4697c4aca1288..3276aa0265f70dd15e4e3799070a56954fc45c5f 100644 (file)
@@ -8,14 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! higher_order (
+macro_rules! higher_order {
     (subst $lhs:tt => $rhs:tt) => ({
-            macro_rules! anon ( $lhs => $rhs );
+            macro_rules! anon { $lhs => $rhs }
             anon!(1u, 2u, "foo")
     });
-);
+}
 
 fn main() {
     let val = higher_order!(subst ($x:expr, $y:expr, $foo:expr) => (($x + $y, $foo)));
index 496cef9d644e27aa501be360155298f23bc06e9f..07b75389cf4ffaccd8afa83c206c6f02f773a5cb 100644 (file)
@@ -8,37 +8,35 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! mypat(
+macro_rules! mypat {
     () => (
         Some('y')
     )
-);
+}
 
-macro_rules! char_x(
+macro_rules! char_x {
     () => (
         'x'
     )
-);
+}
 
-macro_rules! some(
+macro_rules! some {
     ($x:pat) => (
         Some($x)
     )
-);
+}
 
-macro_rules! indirect(
+macro_rules! indirect {
     () => (
         some!(char_x!())
     )
-);
+}
 
-macro_rules! ident_pat(
+macro_rules! ident_pat {
     ($x:ident) => (
         $x
     )
-);
+}
 
 fn f(c: Option<char>) -> uint {
     match c {
index 97f6e2b50d7c895fd9d27bec6ea9eabf3ceadfd5..4aa1587943413de7cc5fa0be6948fc642054c7ac 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 mod m {
     pub type t = int;
 }
diff --git a/src/test/run-pass/macro-reexport-no-intermediate-use.rs b/src/test/run-pass/macro-reexport-no-intermediate-use.rs
new file mode 100644 (file)
index 0000000..77ef942
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:macro_reexport_1.rs
+// aux-build:macro_reexport_2_no_use.rs
+// ignore-stage1
+
+#[macro_use] #[no_link]
+extern crate macro_reexport_2_no_use;
+
+fn main() {
+    assert_eq!(reexported!(), 3u);
+}
diff --git a/src/test/run-pass/macro-reexport.rs b/src/test/run-pass/macro-reexport.rs
new file mode 100644 (file)
index 0000000..9701610
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2014 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.
+
+// aux-build:macro_reexport_1.rs
+// aux-build:macro_reexport_2.rs
+// ignore-stage1
+
+#[macro_use] #[no_link]
+extern crate macro_reexport_2;
+
+fn main() {
+    assert_eq!(reexported!(), 3u);
+}
index 7be49e1acd844db43843174b439a7a16f19ca751..cb5370c8bcba1b1f27b1c8ee12a8276485d883dc 100644 (file)
 
 // ignore-pretty - token trees can't pretty print
 
-#![feature(macro_rules)]
-
-macro_rules! myfn(
+macro_rules! myfn {
     ( $f:ident, ( $( $x:ident ),* ), $body:block ) => (
         fn $f( $( $x : int),* ) -> int $body
     )
-);
+}
 
 myfn!(add, (a,b), { return a+b; } );
 
 pub fn main() {
 
-    macro_rules! mylet(
+    macro_rules! mylet {
         ($x:ident, $val:expr) => (
             let $x = $val;
         )
-    );
+    }
 
     mylet!(y, 8i*2);
     assert_eq!(y, 16i);
@@ -35,9 +33,9 @@ macro_rules! mylet(
 
     assert_eq!(mult(2, add(4,4)), 16);
 
-    macro_rules! actually_an_expr_macro (
+    macro_rules! actually_an_expr_macro {
         () => ( 16i )
-    );
+    }
 
     assert_eq!({ actually_an_expr_macro!() }, 16i);
 
diff --git a/src/test/run-pass/macro-use-all-and-none.rs b/src/test/run-pass/macro-use-all-and-none.rs
new file mode 100644 (file)
index 0000000..b469102
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use]
+#[macro_use()]
+extern crate two_macros;
+
+pub fn main() {
+    macro_one!();
+    macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-all.rs b/src/test/run-pass/macro-use-all.rs
new file mode 100644 (file)
index 0000000..cf72d2c
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use]
+extern crate two_macros;
+
+pub fn main() {
+    macro_one!();
+    macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-both.rs b/src/test/run-pass/macro-use-both.rs
new file mode 100644 (file)
index 0000000..4b0814b
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one, macro_two)]
+extern crate two_macros;
+
+pub fn main() {
+    macro_one!();
+    macro_two!();
+}
diff --git a/src/test/run-pass/macro-use-one.rs b/src/test/run-pass/macro-use-one.rs
new file mode 100644 (file)
index 0000000..7911fec
--- /dev/null
@@ -0,0 +1,19 @@
+// 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.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_two)]
+extern crate two_macros;
+
+pub fn main() {
+    macro_two!();
+}
index 631fc8666713df8ea36403600d8b56698c8c86f0..3f9d07466cc8197e3ba3de62f8bd733f555a070e 100644 (file)
 
 // compile-flags: --cfg foo
 
-#![feature(macro_rules)]
-
 #[cfg(foo)]
-macro_rules! foo( () => (1i) );
+macro_rules! foo { () => (1i) }
 
 #[cfg(not(foo))]
-macro_rules! foo( () => (2i) );
+macro_rules! foo { () => (2i) }
 
 pub fn main() {
     assert_eq!(foo!(), 1i);
index 3ac0d47e61a63665b8a8e339f16e205d55bd8e0d..f90a0dfa6b31e41c2bec64082769b381dbe2e19a 100644 (file)
@@ -8,13 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 #[cfg(foo)]
-macro_rules! foo( () => (1i) );
+macro_rules! foo { () => (1i) }
 
 #[cfg(not(foo))]
-macro_rules! foo( () => (2i) );
+macro_rules! foo { () => (2i) }
 
 pub fn main() {
     assert_eq!(foo!(), 2i);
index a6e579ddff3045091f33f64be39ef169ba2faa8a..93bb9557604c49cd9d4e61fa1373b74edd7485bf 100644 (file)
@@ -8,11 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 use std::thread::Thread;
 
-macro_rules! expr (($e: expr) => { $e });
+macro_rules! expr { ($e: expr) => { $e } }
 
 macro_rules! spawn {
     ($($code: tt)*) => {
index a776999ec8a0010483076ec3283202eae7d579d5..e4886ddaa0ed3155943fe8221cec54a23a66f638 100644 (file)
@@ -8,19 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 enum Foo {
     B { b1: int, bb1: int},
 }
 
-macro_rules! match_inside_expansion(
+macro_rules! match_inside_expansion {
     () => (
         match (Foo::B { b1:29 , bb1: 100}) {
             Foo::B { b1:b2 , bb1:bb2 } => b2+bb2
         }
     )
-);
+}
 
 pub fn main() {
     assert_eq!(match_inside_expansion!(),129);
index 482fdf5b1d040c6789fc4a142aa3f36d8dab8085..984f675b4dc7ddab5e0ba6183ebcc25d4ca74d2b 100644 (file)
 
 // ignore-test #9384
 
-#![feature(macro_rules)]
-
 // shouldn't affect evaluation of $ex.
-macro_rules! bad_macro (($ex:expr) => (
+macro_rules! bad_macro ($ex:expr) => (
     {match 9 {_x => $ex}}
-))
+)}
 
 fn main() {
     match 8 {
index 9151564b3407be7afa65f964562ccf51d1b57080..8b41670734f95bee52407cf7c9065ef205728e05 100644 (file)
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
-macro_rules! quote_tokens ( () => (()) );
+macro_rules! quote_tokens { () => (()) }
 
 pub fn main() {
     quote_tokens!();
index 2660de619e9c775f709159ac750df76c67845c96..9b9a7f68995f7e90456ef1753fd93190d652a07d 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 use std::{option, mem};
 
 // Iota-reduction is a rule in the Calculus of (Co-)Inductive Constructions,
index afc22be38b8a48b16b542a642f46a8418cea235e..02fc0cf0291d43ba23e1eee7986f7efa39460e93 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 use std::mem;
 
 enum E<T> { Thing(int, T), Nothing((), ((), ()), [i8; 0]) }
diff --git a/src/test/run-pass/phase-use-ignored.rs b/src/test/run-pass/phase-use-ignored.rs
deleted file mode 100644 (file)
index 5015e43..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014 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.
-
-
-#![feature(phase)]
-
-#[phase(plugin)]
-use std::mem;
-
-fn main() {}
-
diff --git a/src/test/run-pass/plugin-args-1.rs b/src/test/run-pass/plugin-args-1.rs
new file mode 100644 (file)
index 0000000..5a91f60
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+// aux-build:plugin_args.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[no_link]
+#[plugin]
+extern crate plugin_args;
+
+fn main() {
+    assert_eq!(plugin_args!(), "#[plugin]");
+}
diff --git a/src/test/run-pass/plugin-args-2.rs b/src/test/run-pass/plugin-args-2.rs
new file mode 100644 (file)
index 0000000..d0ac22a
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+// aux-build:plugin_args.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[no_link]
+#[plugin()]
+extern crate plugin_args;
+
+fn main() {
+    assert_eq!(plugin_args!(), "#[plugin()]");
+}
diff --git a/src/test/run-pass/plugin-args-3.rs b/src/test/run-pass/plugin-args-3.rs
new file mode 100644 (file)
index 0000000..7cac8ac
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+// aux-build:plugin_args.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[no_link]
+#[plugin(hello(there), how(are="you"))]
+extern crate plugin_args;
+
+fn main() {
+    assert_eq!(plugin_args!(), "#[plugin(hello(there), how(are = \"you\"))]");
+}
diff --git a/src/test/run-pass/plugin-args-4.rs b/src/test/run-pass/plugin-args-4.rs
new file mode 100644 (file)
index 0000000..8563c8c
--- /dev/null
@@ -0,0 +1,22 @@
+// 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.
+
+// aux-build:plugin_args.rs
+// ignore-stage1
+
+#![feature(plugin)]
+
+#[no_link]
+#[plugin="foobar"]
+extern crate plugin_args;
+
+fn main() {
+    assert_eq!(plugin_args!(), "#[plugin = \"foobar\"]");
+}
index 2612483ded486e8713b7cc4c95a3199f0f9ad18e..95f90ebbf8edf89589de19a82bdbe021e07bd91c 100644 (file)
@@ -10,8 +10,7 @@
 
 // exec-env:RUST_LOG=rust-log-filter/f.o
 
-#![feature(phase)]
-#[phase(plugin,link)]
+#[macro_use]
 extern crate log;
 
 use std::sync::mpsc::{channel, Sender, Receiver};
index 247fa6453b831642fbee031d080fcbc1ba481239..46daa6594303c51b1c9a587a705ae08652ff6ccc 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 use std::mem::size_of;
 
 #[derive(PartialEq, Show)]
index bc9a371edf7ce2fd1a339e144b6f3b9371a1f8b3..235c4e74d085740f5fa9408b65ce2097c245af55 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-comment.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b;
 
index 6599e493d25a1669d0251597d9d19aa1e6f1e8f0..365960b96e4e956a2de4b7cabf09baa7b6f50b10 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-doc.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b;
 
index f4bfe3d8c7c982f6e7da2efdc5967cc1afd40130..a0dbc96cdb02abe7eddcc721f9016a439d381c00 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-macro.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b;
 
index 7f702bd7ab553b59e1ed86662cf7d1ae5e10c9d6..98b7663c58ebb1f9e3e0d239cdda759036511d38 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-no-change.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b;
 
index b5a84843a545b2df72f1d998542a1e43df860b3e..650f76d729a54a676fe64c6748ca566d110445a0 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-redundant-cfg.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b;
 
index 4a8058c96643eb040e90cdff8469c9c13606736c..6612c93e90bc536e8b41ecb8c13a2fde180fff9f 100644 (file)
@@ -13,8 +13,6 @@
 // aux-build:svh-b.rs
 // aux-build:svh-a-whitespace.rs
 
-#![feature(macro_rules)]
-
 extern crate a;
 extern crate b;
 
index f6708536a9d99280fd78ac85fe18b5fe5f60540f..f85305cf31926256c7f97082273443cb04f4ee7c 100644 (file)
@@ -11,8 +11,6 @@
 // This test is brittle!
 // ignore-pretty - the pretty tests lose path information, breaking include!
 
-#![feature(macro_rules)]
-
 pub mod m1 {
     pub mod m2 {
         pub fn where_am_i() -> String {
@@ -21,12 +19,12 @@ pub fn where_am_i() -> String {
     }
 }
 
-macro_rules! indirect_line( () => ( line!() ) );
+macro_rules! indirect_line { () => ( line!() ) }
 
 pub fn main() {
-    assert_eq!(line!(), 27);
+    assert_eq!(line!(), 25);
     //assert!((column!() == 11));
-    assert_eq!(indirect_line!(), 29);
+    assert_eq!(indirect_line!(), 27);
     assert!((file!().ends_with("syntax-extension-source-utils.rs")));
     assert_eq!(stringify!((2*3) + 5).to_string(), "( 2 * 3 ) + 5".to_string());
     assert!(include!("syntax-extension-source-utils-files/includeme.\
@@ -44,7 +42,7 @@ pub fn main() {
     // The Windows tests are wrapped in an extra module for some reason
     assert!((m1::m2::where_am_i().as_slice().ends_with("m1::m2")));
 
-    assert!(match (47, "( 2 * 3 ) + 5") {
+    assert!(match (45, "( 2 * 3 ) + 5") {
         (line!(), stringify!((2*3) + 5)) => true,
         _ => false
     })
index 2598679f92107c52cc7009dc98bd0a368490b01e..4ab089b6eaa1c8420d34414cf1305e956041a509 100644 (file)
@@ -16,7 +16,6 @@
 // one test task to ensure that errors are timeouts, not file descriptor
 // exhaustion.
 
-#![feature(macro_rules)]
 #![allow(experimental)]
 #![reexport_test_harness_main = "test_main"]
 
index 62b61c153c7077d8330ad997fd17d9a055ff7570..7d226aa9420320b95bd35e40c88735d9b6a83834 100644 (file)
@@ -12,8 +12,7 @@
 // ignore-android needs extra network permissions
 // exec-env:RUST_LOG=debug
 
-#![feature(phase)]
-#[phase(plugin, link)]
+#[macro_use]
 extern crate log;
 extern crate libc;
 
diff --git a/src/test/run-pass/two-macro-use.rs b/src/test/run-pass/two-macro-use.rs
new file mode 100644 (file)
index 0000000..51c0b75
--- /dev/null
@@ -0,0 +1,21 @@
+// 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.
+
+// aux-build:two_macros.rs
+// ignore-stage1
+
+#[macro_use(macro_one)]
+#[macro_use(macro_two)]
+extern crate two_macros;
+
+pub fn main() {
+    macro_one!();
+    macro_two!();
+}
index 4dec227d52020aa44bdaa6150bb1a2d157947c3e..673e852356266bafc5c35152453260d889201923 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 enum T {
     A(int),
     B(f64)
@@ -20,7 +18,7 @@ enum T {
 // doesn't cause capture. Making this macro hygienic (as I've done)
 // could very well make this test case completely pointless....
 
-macro_rules! test(
+macro_rules! test {
     ($id1:ident, $id2:ident, $e:expr) => (
         fn foo(a:T, b:T) -> T {
             match (a, b) {
@@ -30,7 +28,7 @@ fn foo(a:T, b:T) -> T {
             }
         }
     )
-);
+}
 
 test!(x,y,x + y);
 
diff --git a/src/test/run-pass/vec-macro-no-std.rs b/src/test/run-pass/vec-macro-no-std.rs
new file mode 100644 (file)
index 0000000..c04afff
--- /dev/null
@@ -0,0 +1,39 @@
+// Copyright 2014 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.
+
+#![feature(lang_items)]
+#![no_std]
+
+#[macro_use]
+extern crate core;
+extern crate libc;
+
+#[macro_use]
+extern crate collections;
+
+use core::option::Option::Some;
+use core::slice::SliceExt;
+use collections::vec::Vec;
+
+#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
+#[lang = "eh_personality"] extern fn eh_personality() {}
+#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
+
+// Issue #16806
+
+#[start]
+fn start(_argc: int, _argv: *const *const u8) -> int {
+    let x: Vec<u8> = vec![0, 1, 2];
+    match x.last() {
+        Some(&2) => (),
+        _ => panic!(),
+    }
+    0
+}
index 2c784dade571121a0049e2afee5dbab80c541d96..a263501f8fe71fbd276e2f2a9165c472a2b17a7d 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(macro_rules)]
-
 macro_rules! vec [
     ($($e:expr),*) => ({
         let mut _temp = ::std::vec::Vec::new();