]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #20610 : alexcrichton/rust/rollup, r=alexcrichton
authorbors <bors@rust-lang.org>
Tue, 6 Jan 2015 08:25:32 +0000 (08:25 +0000)
committerbors <bors@rust-lang.org>
Tue, 6 Jan 2015 08:25:32 +0000 (08:25 +0000)
733 files changed:
mk/docs.mk
mk/main.mk
src/compiletest/compiletest.rs
src/doc/complement-lang-faq.md
src/doc/guide-ffi.md
src/doc/guide-macros.md
src/doc/guide-ownership.md
src/doc/guide-plugin.md
src/doc/guide-testing.md
src/doc/guide.md
src/doc/reference.md
src/doc/uptack.tex [new file with mode: 0644]
src/etc/kate/rust.xml
src/etc/vim/syntax/rust.vim
src/grammar/verify.rs
src/liballoc/arc.rs
src/liballoc/boxed.rs
src/liballoc/lib.rs
src/liballoc/rc.rs
src/libcollections/binary_heap.rs
src/libcollections/btree/map.rs
src/libcollections/btree/node.rs
src/libcollections/btree/set.rs
src/libcollections/dlist.rs
src/libcollections/lib.rs
src/libcollections/macros.rs
src/libcollections/ring_buf.rs
src/libcollections/slice.rs
src/libcollections/str.rs
src/libcollections/string.rs
src/libcollections/vec.rs
src/libcore/atomic.rs
src/libcore/borrow.rs
src/libcore/cell.rs
src/libcore/char.rs
src/libcore/clone.rs
src/libcore/cmp.rs
src/libcore/fmt/mod.rs
src/libcore/hash/mod.rs
src/libcore/hash/sip.rs
src/libcore/iter.rs
src/libcore/kinds.rs
src/libcore/lib.rs
src/libcore/macros.rs
src/libcore/mem.rs
src/libcore/num/float_macros.rs
src/libcore/num/int_macros.rs
src/libcore/num/uint_macros.rs
src/libcore/ops.rs
src/libcore/option.rs
src/libcore/prelude.rs
src/libcore/raw.rs
src/libcore/result.rs
src/libcore/slice.rs
src/libcore/str/mod.rs
src/libcoretest/hash/mod.rs
src/libcoretest/iter.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/libgraphviz/lib.rs
src/libgraphviz/maybe_owned_vec.rs
src/liblog/lib.rs
src/liblog/macros.rs
src/librand/chacha.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/builtin.rs
src/librustc/lint/context.rs
src/librustc/lint/mod.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/loader.rs
src/librustc/middle/cfg/construct.rs
src/librustc/middle/check_match.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/infer/error_reporting.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/infer/region_inference/mod.rs
src/librustc/middle/intrinsicck.rs
src/librustc/middle/mem_categorization.rs
src/librustc/middle/traits/coherence.rs
src/librustc/middle/traits/project.rs
src/librustc/middle/traits/util.rs
src/librustc/middle/ty.rs
src/librustc/plugin/load.rs
src/librustc/plugin/mod.rs
src/librustc/plugin/registry.rs
src/librustc/session/config.rs
src/librustc/session/mod.rs
src/librustc/util/nodemap.rs
src/librustc/util/ppaux.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_llvm/archive_ro.rs
src/librustc_llvm/lib.rs
src/librustc_resolve/lib.rs
src/librustc_trans/back/lto.rs
src/librustc_trans/back/write.rs
src/librustc_trans/lib.rs
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/asm.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/builder.rs
src/librustc_trans/trans/cabi_x86_64.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/context.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/foreign.rs
src/librustc_trans/trans/glue.rs
src/librustc_trans/trans/llrepr.rs
src/librustc_trans/trans/macros.rs
src/librustc_trans/trans/meth.rs
src/librustc_trans/trans/mod.rs
src/librustc_trans/trans/type_.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/_match.rs
src/librustc_typeck/check/callee.rs
src/librustc_typeck/check/demand.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/regionmanip.rs
src/librustc_typeck/coherence/orphan.rs
src/librustc_typeck/lib.rs
src/librustdoc/clean/mod.rs
src/librustdoc/flock.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/markdown.rs
src/librustdoc/html/render.rs
src/librustdoc/html/static/main.css
src/librustdoc/html/static/main.js
src/librustdoc/lib.rs
src/librustdoc/visit_ast.rs
src/libserialize/base64.rs
src/libserialize/hex.rs
src/libserialize/json.rs
src/libserialize/json_stage0.rs
src/libserialize/lib.rs
src/libserialize/serialize.rs
src/libserialize/serialize_stage0.rs
src/libstd/ascii.rs
src/libstd/bitflags.rs
src/libstd/c_str.rs [deleted file]
src/libstd/c_vec.rs [deleted file]
src/libstd/collections/hash/map.rs
src/libstd/collections/hash/set.rs
src/libstd/collections/hash/table.rs
src/libstd/collections/mod.rs
src/libstd/dynamic_lib.rs
src/libstd/ffi/c_str.rs [new file with mode: 0644]
src/libstd/ffi/mod.rs [new file with mode: 0644]
src/libstd/hash.rs
src/libstd/io/buffered.rs
src/libstd/io/mod.rs
src/libstd/io/net/pipe.rs
src/libstd/io/process.rs
src/libstd/io/tempfile.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/os.rs
src/libstd/path/mod.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/prelude/mod.rs
src/libstd/prelude/v1.rs
src/libstd/rand/mod.rs
src/libstd/rand/os.rs
src/libstd/rt/args.rs
src/libstd/rt/backtrace.rs
src/libstd/rt/macros.rs
src/libstd/rt/mod.rs
src/libstd/rt/unwind.rs
src/libstd/rt/util.rs
src/libstd/sync/condvar.rs
src/libstd/sync/mod.rs
src/libstd/sync/mpsc/mod.rs
src/libstd/sync/mpsc/mpsc_queue.rs
src/libstd/sync/mutex.rs
src/libstd/sync/once.rs
src/libstd/sync/poison.rs
src/libstd/sync/rwlock.rs
src/libstd/sync/semaphore.rs
src/libstd/sys/common/mod.rs
src/libstd/sys/common/net.rs
src/libstd/sys/unix/backtrace.rs
src/libstd/sys/unix/fs.rs
src/libstd/sys/unix/mod.rs
src/libstd/sys/unix/os.rs
src/libstd/sys/unix/pipe.rs
src/libstd/sys/unix/process.rs
src/libstd/sys/unix/timer.rs
src/libstd/sys/windows/backtrace.rs
src/libstd/sys/windows/c.rs
src/libstd/sys/windows/fs.rs
src/libstd/sys/windows/pipe.rs
src/libstd/sys/windows/process.rs
src/libstd/thread.rs
src/libstd/thread_local/mod.rs
src/libstd/thread_local/scoped.rs
src/libstd/time/duration.rs
src/libstd/tuple.rs
src/libsyntax/ast.rs
src/libsyntax/ast_util.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/generic/mod.rs
src/libsyntax/ext/deriving/hash.rs
src/libsyntax/ext/deriving/mod.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/quote.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/obsolete.rs
src/libsyntax/parse/parser.rs
src/libsyntax/parse/token.rs
src/libsyntax/print/pprust.rs
src/libsyntax/show_span.rs
src/libsyntax/std_inject.rs
src/libsyntax/util/interner.rs
src/libsyntax/visit.rs
src/libterm/lib.rs
src/libterm/terminfo/parser/compiled.rs
src/libtest/lib.rs
src/libtest/stats.rs
src/libunicode/u_str.rs
src/llvm
src/rustllvm/llvm-auto-clean-trigger
src/test/auxiliary/associated-types-cc-lib.rs
src/test/auxiliary/default_type_params_xc.rs
src/test/auxiliary/issue-13560-3.rs
src/test/auxiliary/issue-16643.rs
src/test/auxiliary/issue_20389.rs
src/test/auxiliary/issue_2316_b.rs
src/test/auxiliary/lang-item-public.rs
src/test/auxiliary/linkage-visibility.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/namespaced_enum_emulate_flat.rs
src/test/auxiliary/overloaded_autoderef_xc.rs
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/syntax-extension-with-dll-deps-2.rs
src/test/auxiliary/trait_inheritance_overloading_xc.rs
src/test/auxiliary/traitimpl.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/rt-messaging-ping-pong.rs
src/test/bench/shootout-fasta.rs
src/test/bench/shootout-k-nucleotide.rs
src/test/bench/shootout-mandelbrot.rs
src/test/bench/shootout-meteor.rs
src/test/bench/shootout-regex-dna.rs
src/test/bench/shootout-reverse-complement.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/associated-type-projection-from-multiple-supertraits.rs
src/test/compile-fail/associated-type-projection-from-supertrait.rs
src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
src/test/compile-fail/associated-types-binding-to-type-defined-in-supertrait.rs
src/test/compile-fail/associated-types-bound-failure.rs
src/test/compile-fail/associated-types-eq-1.rs
src/test/compile-fail/associated-types-eq-2.rs
src/test/compile-fail/associated-types-eq-3.rs
src/test/compile-fail/associated-types-eq-expr-path.rs
src/test/compile-fail/associated-types-eq-hr.rs
src/test/compile-fail/associated-types-feature-gate.rs [deleted file]
src/test/compile-fail/associated-types-for-unimpl-trait.rs
src/test/compile-fail/associated-types-in-ambiguous-context.rs
src/test/compile-fail/associated-types-incomplete-object.rs
src/test/compile-fail/associated-types-invalid-trait-ref-issue-18865.rs [new file with mode: 0644]
src/test/compile-fail/associated-types-issue-17359.rs [new file with mode: 0644]
src/test/compile-fail/associated-types-issue-20346.rs
src/test/compile-fail/associated-types-no-suitable-bound.rs
src/test/compile-fail/associated-types-no-suitable-supertrait.rs
src/test/compile-fail/associated-types-path-1.rs
src/test/compile-fail/associated-types-path-2.rs
src/test/compile-fail/associated-types-project-from-hrtb-explicit.rs
src/test/compile-fail/associated-types-project-from-hrtb-in-fn-body.rs
src/test/compile-fail/associated-types-project-from-hrtb-in-fn.rs
src/test/compile-fail/associated-types-project-from-hrtb-in-struct.rs
src/test/compile-fail/associated-types-project-from-hrtb-in-trait-method.rs
src/test/compile-fail/associated-types-unconstrained.rs
src/test/compile-fail/associated-types-unsized.rs
src/test/compile-fail/binop-consume-args.rs
src/test/compile-fail/binop-move-semantics.rs
src/test/compile-fail/borrowck-borrow-overloaded-auto-deref-mut.rs
src/test/compile-fail/borrowck-borrow-overloaded-auto-deref.rs
src/test/compile-fail/borrowck-borrow-overloaded-deref-mut.rs
src/test/compile-fail/borrowck-borrow-overloaded-deref.rs
src/test/compile-fail/borrowck-loan-in-overloaded-op.rs
src/test/compile-fail/borrowck-loan-rcvr-overloaded-op.rs
src/test/compile-fail/borrowck-overloaded-index-2.rs
src/test/compile-fail/borrowck-overloaded-index-autoderef.rs
src/test/compile-fail/borrowck-overloaded-index.rs
src/test/compile-fail/cleanup-rvalue-scopes-cf.rs
src/test/compile-fail/coherence-all-remote.rs
src/test/compile-fail/coherence-bigint-int.rs [new file with mode: 0644]
src/test/compile-fail/coherence-bigint-param.rs
src/test/compile-fail/coherence-bigint-vecint.rs [new file with mode: 0644]
src/test/compile-fail/coherence-cross-crate-conflict.rs
src/test/compile-fail/coherence-iterator-vec-any-elem.rs [deleted file]
src/test/compile-fail/coherence-lone-type-parameter.rs
src/test/compile-fail/coherence-orphan.rs
src/test/compile-fail/coherence-overlapping-pairs.rs
src/test/compile-fail/coherence-pair-covered-uncovered.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/drop-on-non-struct.rs
src/test/compile-fail/dst-bad-assign-2.rs
src/test/compile-fail/dst-bad-assign.rs
src/test/compile-fail/dst-bad-coerce1.rs
src/test/compile-fail/dst-bad-coerce2.rs
src/test/compile-fail/dst-bad-coerce3.rs
src/test/compile-fail/dst-bad-coerce4.rs
src/test/compile-fail/dst-bad-coercions.rs
src/test/compile-fail/dst-bad-deep.rs
src/test/compile-fail/dst-index.rs
src/test/compile-fail/dst-object-from-unsized-type.rs
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-default-type-param-usage.rs [deleted file]
src/test/compile-fail/gated-default-type-params.rs [deleted file]
src/test/compile-fail/gated-glob-imports.rs [deleted file]
src/test/compile-fail/gated-macro-rules.rs [deleted file]
src/test/compile-fail/generic-impl-less-params-with-defaults.rs
src/test/compile-fail/generic-impl-more-params-with-defaults.rs
src/test/compile-fail/generic-non-trailing-defaults.rs
src/test/compile-fail/generic-type-less-params-with-defaults.rs
src/test/compile-fail/generic-type-more-params-with-defaults.rs
src/test/compile-fail/generic-type-params-forward-mention.rs
src/test/compile-fail/generic-type-params-name-repr.rs
src/test/compile-fail/glob-resolve1.rs
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/import-glob-0.rs
src/test/compile-fail/import-glob-circular.rs
src/test/compile-fail/import-shadow-1.rs
src/test/compile-fail/import-shadow-2.rs
src/test/compile-fail/import-shadow-3.rs
src/test/compile-fail/import-shadow-4.rs
src/test/compile-fail/import-shadow-5.rs
src/test/compile-fail/import-shadow-6.rs
src/test/compile-fail/import-shadow-7.rs
src/test/compile-fail/infinite-autoderef.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-1697.rs
src/test/compile-fail/issue-17904.rs [new file with mode: 0644]
src/test/compile-fail/issue-18389.rs
src/test/compile-fail/issue-18566.rs
src/test/compile-fail/issue-18611.rs
src/test/compile-fail/issue-18819.rs
src/test/compile-fail/issue-18959.rs
src/test/compile-fail/issue-19883.rs
src/test/compile-fail/issue-20005.rs
src/test/compile-fail/issue-4366-2.rs
src/test/compile-fail/issue-4366.rs
src/test/compile-fail/issue-6596.rs
src/test/compile-fail/issue-8208.rs
src/test/compile-fail/lint-missing-doc.rs
src/test/compile-fail/lint-raw-ptr-derive.rs [new file with mode: 0644]
src/test/compile-fail/lint-raw-ptr-deriving.rs [deleted file]
src/test/compile-fail/lint-stability.rs
src/test/compile-fail/lint-unsafe-block.rs
src/test/compile-fail/lint-unused-extern-crate.rs
src/test/compile-fail/lint-unused-imports.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/macros-no-semicolon.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/mut-pattern-internal-mutability.rs [new file with mode: 0644]
src/test/compile-fail/mut-pattern-mismatched.rs [new file with mode: 0644]
src/test/compile-fail/name-clash-nullary.rs
src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs
src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs
src/test/compile-fail/no-link.rs [new file with mode: 0644]
src/test/compile-fail/obsolete-for-sized.rs [new file with mode: 0644]
src/test/compile-fail/pattern-macro-hygiene.rs
src/test/compile-fail/privacy-ns1.rs
src/test/compile-fail/privacy-ns2.rs
src/test/compile-fail/privacy1.rs
src/test/compile-fail/privacy2.rs
src/test/compile-fail/privacy3.rs
src/test/compile-fail/privacy4.rs
src/test/compile-fail/recursion_limit.rs
src/test/compile-fail/regions-close-associated-type-into-object.rs [new file with mode: 0644]
src/test/compile-fail/regions-close-param-into-object.rs [new file with mode: 0644]
src/test/compile-fail/regions-pattern-typing-issue-19552.rs [new file with mode: 0644]
src/test/compile-fail/regions-pattern-typing-issue-19997.rs [new file with mode: 0644]
src/test/compile-fail/required-lang-item.rs
src/test/compile-fail/static-reference-to-fn-2.rs
src/test/compile-fail/std-uncopyable-atomics.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/transmute-fat-pointers.rs
src/test/compile-fail/transmute-impl.rs
src/test/compile-fail/unboxed-closure-sugar-default.rs
src/test/compile-fail/unboxed-closure-sugar-equiv.rs
src/test/compile-fail/unboxed-closure-sugar-lifetime-elision.rs
src/test/compile-fail/unboxed-closure-sugar-region.rs
src/test/compile-fail/unsized-bare-typaram.rs
src/test/compile-fail/unsized-enum.rs
src/test/compile-fail/unsized-inherent-impl-self-type.rs
src/test/compile-fail/unsized-struct.rs
src/test/compile-fail/unsized-trait-impl-self-type.rs
src/test/compile-fail/unsized-trait-impl-trait-arg.rs
src/test/compile-fail/unsized.rs
src/test/compile-fail/unsized3.rs
src/test/compile-fail/unsized4.rs
src/test/compile-fail/unsized5.rs
src/test/compile-fail/unsized6.rs
src/test/compile-fail/unsized7.rs
src/test/compile-fail/while-let.rs
src/test/compile-fail/wrong-mul-method-signature.rs
src/test/debuginfo/lexical-scope-with-macro.rs
src/test/pretty/issue-4264.pp
src/test/run-fail/glob-use-std.rs
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-valgrind/dst-dtor-1.rs
src/test/run-pass-valgrind/dst-dtor-2.rs
src/test/run-pass/associated-types-basic.rs
src/test/run-pass/associated-types-binding-in-where-clause.rs
src/test/run-pass/associated-types-bound.rs
src/test/run-pass/associated-types-cc.rs
src/test/run-pass/associated-types-conditional-dispatch.rs
src/test/run-pass/associated-types-constant-type.rs
src/test/run-pass/associated-types-eq-obj.rs
src/test/run-pass/associated-types-impl-redirect.rs
src/test/run-pass/associated-types-in-default-method.rs
src/test/run-pass/associated-types-in-fn.rs
src/test/run-pass/associated-types-in-impl-generics.rs
src/test/run-pass/associated-types-in-inherent-method.rs
src/test/run-pass/associated-types-issue-20371.rs
src/test/run-pass/associated-types-normalize-in-bounds-ufcs.rs
src/test/run-pass/associated-types-normalize-in-bounds.rs
src/test/run-pass/associated-types-projection-bound-in-supertraits.rs
src/test/run-pass/associated-types-qualified-path-with-trait-with-type-parameters.rs
src/test/run-pass/associated-types-resolve-lifetime.rs
src/test/run-pass/associated-types-return.rs
src/test/run-pass/associated-types-simple.rs
src/test/run-pass/associated-types-sugar-path.rs
src/test/run-pass/associated-types-where-clause-impl-ambiguity.rs
src/test/run-pass/borrowck-macro-interaction-issue-6304.rs
src/test/run-pass/c-stack-returning-int64.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/coherence-bigint-int.rs [deleted file]
src/test/run-pass/coherence-bigint-vecint.rs [deleted file]
src/test/run-pass/coherence-iterator-vec-any-elem.rs [new file with mode: 0644]
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/const-str-ptr.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/dst-deref-mut.rs
src/test/run-pass/dst-deref.rs
src/test/run-pass/dst-index.rs
src/test/run-pass/enum-discrim-width-stuff.rs
src/test/run-pass/eq-multidispatch.rs
src/test/run-pass/exponential-notation.rs
src/test/run-pass/export-glob-imports-target.rs
src/test/run-pass/fixup-deref-mut.rs
src/test/run-pass/foreign-fn-linkname.rs
src/test/run-pass/generic-default-type-params-cross-crate.rs
src/test/run-pass/generic-default-type-params.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/import-glob-0.rs
src/test/run-pass/import-glob-crate.rs
src/test/run-pass/import-in-block.rs
src/test/run-pass/intrinsics-integer.rs
src/test/run-pass/intrinsics-math.rs
src/test/run-pass/issue-11709.rs
src/test/run-pass/issue-13167.rs
src/test/run-pass/issue-13264.rs
src/test/run-pass/issue-14330.rs
src/test/run-pass/issue-14919.rs
src/test/run-pass/issue-14933.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-15734.rs
src/test/run-pass/issue-16596.rs
src/test/run-pass/issue-16597.rs
src/test/run-pass/issue-16774.rs
src/test/run-pass/issue-17732.rs
src/test/run-pass/issue-17897.rs
src/test/run-pass/issue-17904.rs [new file with mode: 0644]
src/test/run-pass/issue-18188.rs
src/test/run-pass/issue-18906.rs
src/test/run-pass/issue-19081.rs
src/test/run-pass/issue-19121.rs
src/test/run-pass/issue-19129-1.rs
src/test/run-pass/issue-19129-2.rs
src/test/run-pass/issue-19479.rs
src/test/run-pass/issue-19631.rs
src/test/run-pass/issue-19632.rs
src/test/run-pass/issue-19850.rs
src/test/run-pass/issue-20009.rs
src/test/run-pass/issue-20389.rs
src/test/run-pass/issue-2526-a.rs
src/test/run-pass/issue-3609.rs
src/test/run-pass/issue-3743.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-7663.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/method-normalize-bounds-issue-20604.rs [new file with mode: 0644]
src/test/run-pass/method-recursive-blanket-impl.rs
src/test/run-pass/method-where-clause.rs [new file with mode: 0644]
src/test/run-pass/namespaced-enum-emulate-flat.rs
src/test/run-pass/namespaced-enum-glob-import-xcrate.rs
src/test/run-pass/namespaced-enum-glob-import.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/operator-multidispatch.rs
src/test/run-pass/operator-overloading.rs
src/test/run-pass/overloaded-autoderef-count.rs
src/test/run-pass/overloaded-autoderef-indexing.rs
src/test/run-pass/overloaded-autoderef-order.rs
src/test/run-pass/overloaded-autoderef-vtable.rs
src/test/run-pass/overloaded-calls-param-vtables.rs
src/test/run-pass/overloaded-deref-count.rs
src/test/run-pass/overloaded-index-assoc-list.rs
src/test/run-pass/overloaded-index-autoderef.rs
src/test/run-pass/overloaded-index-in-field.rs
src/test/run-pass/overloaded-index.rs
src/test/run-pass/parse-assoc-type-lt.rs
src/test/run-pass/parse-complex-macro-invoc-op.rs [new file with mode: 0644]
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/privacy-ns.rs
src/test/run-pass/reexport-star.rs
src/test/run-pass/regions-no-bound-in-argument-cleanup.rs
src/test/run-pass/regions-reassign-let-bound-pointer.rs [new file with mode: 0644]
src/test/run-pass/regions-reassign-match-bound-pointer.rs [new file with mode: 0644]
src/test/run-pass/regions-relate-bound-regions-on-closures-to-inference-variables.rs [new file with mode: 0644]
src/test/run-pass/rename-directory.rs
src/test/run-pass/running-with-no-runtime.rs
src/test/run-pass/rust-log-filter.rs
src/test/run-pass/simd-generics.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/tag-exports.rs
src/test/run-pass/tcp-connect-timeouts.rs
src/test/run-pass/tcp-stress.rs
src/test/run-pass/tempfile.rs
src/test/run-pass/trait-inheritance-overloading.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/unsized.rs
src/test/run-pass/unsized2.rs
src/test/run-pass/variadic-ffi.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 2a7ef5164f0e96e811d68d20b7abdecc519011c7..274598feada670d1a94c0347e2353ff74533f058 100644 (file)
@@ -49,8 +49,10 @@ RUSTDOC_HTML_OPTS_NO_CSS = --html-before-content=doc/version_info.html \
 RUSTDOC_HTML_OPTS = $(RUSTDOC_HTML_OPTS_NO_CSS) --markdown-css rust.css
 
 PANDOC_BASE_OPTS := --standalone --toc --number-sections
-PANDOC_TEX_OPTS = $(PANDOC_BASE_OPTS) --include-before-body=doc/version.tex \
-       --from=markdown --include-before-body=doc/footer.tex --to=latex
+PANDOC_TEX_OPTS = $(PANDOC_BASE_OPTS) --from=markdown --to=latex \
+       --include-before-body=doc/version.tex \
+       --include-before-body=doc/footer.tex \
+       --include-in-header=doc/uptack.tex
 PANDOC_EPUB_OPTS = $(PANDOC_BASE_OPTS) --to=epub
 
 # The rustdoc executable...
@@ -155,6 +157,9 @@ doc/footer.tex: $(D)/footer.inc | doc/
        @$(call E, pandoc: $@)
        $(CFG_PANDOC) --from=html --to=latex $< --output=$@
 
+doc/uptack.tex: $(D)/uptack.tex | doc/
+       $(Q)cp $< $@
+
 # HTML (rustdoc)
 DOC_TARGETS += doc/not_found.html
 doc/not_found.html: $(D)/not_found.md $(HTML_DEPS) | doc/
@@ -180,7 +185,7 @@ doc/$(1).epub: $$(D)/$(1).md | doc/
 
 # PDF (md =(pandoc)=> tex =(pdflatex)=> pdf)
 DOC_TARGETS += doc/$(1).tex
-doc/$(1).tex: $$(D)/$(1).md doc/footer.tex doc/version.tex | doc/
+doc/$(1).tex: $$(D)/$(1).md doc/uptack.tex doc/footer.tex doc/version.tex | doc/
        @$$(call E, pandoc: $$@)
        $$(CFG_PANDOC) $$(PANDOC_TEX_OPTS) $$< --output=$$@
 
index 0d9419cccfa83e0299d1c19079ef1114d98990f9..a97e68af59b3808062dd5f8fa09b2ea0a1e6358c 100644 (file)
@@ -13,7 +13,7 @@
 ######################################################################
 
 # The version number
-CFG_RELEASE_NUM=0.13.0
+CFG_RELEASE_NUM=1.0.0
 
 # An optional number to put after the label, e.g. '2' -> '-beta2'
 CFG_BETA_CYCLE=
@@ -29,14 +29,14 @@ endif
 ifeq ($(CFG_RELEASE_CHANNEL),beta)
 # The beta channel is temporarily called 'alpha'
 CFG_RELEASE=$(CFG_RELEASE_NUM)-alpha$(CFG_BETA_CYCLE)
-# When building beta/nightly distributables just reuse the same "beta"
-# name so when we upload we'll always override the previous
-# nighly. This doesn't actually impact the version reported by rustc -
-# it's just for file naming.
-CFG_PACKAGE_VERS=alpha
+CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-alpha$(CFG_BETA_CYCLE)
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),nightly)
 CFG_RELEASE=$(CFG_RELEASE_NUM)-nightly
+# When building nightly distributables just reuse the same "nightly" name
+# so when we upload we'll always override the previous nighly. This
+# doesn't actually impact the version reported by rustc - it's just
+# for file naming.
 CFG_PACKAGE_VERS=nightly
 endif
 ifeq ($(CFG_RELEASE_CHANNEL),dev)
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 9e73863239fbc06b05e807f243b7bb65d99d7cf5..a9a9e0858ec6b7cc387a5b48d2d09b8c5f166b24 100644 (file)
@@ -17,7 +17,7 @@ Some examples that demonstrate different aspects of the language:
 * [sprocketnes], an NES emulator with no GC, using modern Rust conventions
 * The language's general-purpose [hash] function, SipHash-2-4. Bit twiddling, OO, macros
 * The standard library's [HashMap], a sendable hash map in an OO style
-* The extra library's [json] module. Enums and pattern matching
+* The standard library's [json] module. Enums and pattern matching
 
 [sprocketnes]: https://github.com/pcwalton/sprocketnes
 [hash]: https://github.com/rust-lang/rust/blob/master/src/libstd/hash/mod.rs
index b8808eaf57d93e076b5b90829ecd0d45b5317202..7ee1c1a7032a5c4fce6975e1c9d0e0201fe4dbe7 100644 (file)
@@ -451,7 +451,7 @@ them.
 ~~~no_run
 extern crate libc;
 
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::ptr;
 
 #[link(name = "readline")]
@@ -460,11 +460,10 @@ extern {
 }
 
 fn main() {
-    "[my-awesome-shell] $".with_c_str(|buf| {
-        unsafe { rl_prompt = buf; }
-        // get a line, process it
-        unsafe { rl_prompt = ptr::null(); }
-    });
+    let prompt = CString::from_slice(b"[my-awesome-shell] $");
+    unsafe { rl_prompt = prompt.as_ptr(); }
+    // get a line, process it
+    unsafe { rl_prompt = ptr::null(); }
 }
 ~~~
 
@@ -509,23 +508,28 @@ to define a block for all windows systems, not just x86 ones.
 
 # Interoperability with foreign code
 
-Rust guarantees that the layout of a `struct` is compatible with the platform's representation in C
-only if the `#[repr(C)]` attribute is applied to it.  `#[repr(C, packed)]` can be used to lay out
-struct members without padding.  `#[repr(C)]` can also be applied to an enum.
-
-Rust's owned boxes (`Box<T>`) use non-nullable pointers as handles which point to the contained
-object. However, they should not be manually created because they are managed by internal
-allocators. References can safely be assumed to be non-nullable pointers directly to the type.
-However, breaking the borrow checking or mutability rules is not guaranteed to be safe, so prefer
-using raw pointers (`*`) if that's needed because the compiler can't make as many assumptions about
-them.
-
-Vectors and strings share the same basic memory layout, and utilities are available in the `vec` and
-`str` modules for working with C APIs. However, strings are not terminated with `\0`. If you need a
-NUL-terminated string for interoperability with C, you should use the `c_str::to_c_str` function.
-
-The standard library includes type aliases and function definitions for the C standard library in
-the `libc` module, and Rust links against `libc` and `libm` by default.
+Rust guarantees that the layout of a `struct` is compatible with the platform's
+representation in C only if the `#[repr(C)]` attribute is applied to it.
+`#[repr(C, packed)]` can be used to lay out struct members without padding.
+`#[repr(C)]` can also be applied to an enum.
+
+Rust's owned boxes (`Box<T>`) use non-nullable pointers as handles which point
+to the contained object. However, they should not be manually created because
+they are managed by internal allocators. References can safely be assumed to be
+non-nullable pointers directly to the type.  However, breaking the borrow
+checking or mutability rules is not guaranteed to be safe, so prefer using raw
+pointers (`*`) if that's needed because the compiler can't make as many
+assumptions about them.
+
+Vectors and strings share the same basic memory layout, and utilities are
+available in the `vec` and `str` modules for working with C APIs. However,
+strings are not terminated with `\0`. If you need a NUL-terminated string for
+interoperability with C, you should use the `CString` type in the `std::ffi`
+module.
+
+The standard library includes type aliases and function definitions for the C
+standard library in the `libc` module, and Rust links against `libc` and `libm`
+by default.
 
 # The "nullable pointer optimization"
 
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 bf750ecaa8f673acd63f36e7822feb6c0c33465f..414a874082eefdc24fe8acf2bfbdc656351bf93d 100644 (file)
@@ -230,8 +230,9 @@ fn add_one(num: &int) -> int {
 ```
 
 Rust has a feature called 'lifetime elision,' which allows you to not write
-lifetime annotations in certain circumstances. This is one of them. Without
-eliding the lifetimes, `add_one` looks like this:
+lifetime annotations in certain circumstances. This is one of them. We will
+cover the others later. Without eliding the lifetimes, `add_one` looks like
+this:
 
 ```rust
 fn add_one<'a>(num: &'a int) -> int {
@@ -449,6 +450,80 @@ This is the simplest kind of multiple ownership possible. For example, there's
 also `Arc<T>`, which uses more expensive atomic instructions to be the
 thread-safe counterpart of `Rc<T>`.
 
+## Lifetime Elision
+
+Earlier, we mentioned 'lifetime elision,' a feature of Rust which allows you to
+not write lifetime annotations in certain circumstances. All references have a
+lifetime, and so if you elide a lifetime (like `&T` instead of `&'a T`), Rust
+will do three things to determine what those lifetimes should be.
+
+When talking about lifetime elision, we use the term 'input lifetime' and
+'output lifetime'. An 'input liftime' is a lifetime associated with a parameter
+of a function, and an 'output lifetime' is a lifetime associated with the return
+value of a function. For example, this function has an input lifetime:
+
+```{rust,ignore}
+fn foo<'a>(bar: &'a str)
+```
+
+This one has an output lifetime:
+
+```{rust,ignore}
+fn foo<'a>() -> &'a str
+```
+
+This one has a lifetime in both positions:
+
+```{rust,ignore}
+fn foo<'a>(bar: &'a str) -> &'a str
+```
+
+Here are the three rules:
+
+* Each elided lifetime in a function's arguments becomes a distinct lifetime
+  parameter.
+
+* If there is exactly one input lifetime, elided or not, that lifetime is
+  assigned to all elided lifetimes in the return values of that function..
+
+* If there are multiple input lifetimes, but one of them is `&self` or `&mut
+  self`, the lifetime of `self` is assigned to all elided output lifetimes.
+
+Otherwise, it is an error to elide an output lifetime.
+
+### Examples
+
+Here are some examples of functions with elided lifetimes, and the version of
+what the elided lifetimes are expand to:
+
+```{rust,ignore}
+fn print(s: &str);                                      // elided
+fn print<'a>(s: &'a str);                               // expanded
+
+fn debug(lvl: uint, s: &str);                           // elided
+fn debug<'a>(lvl: uint, s: &'a str);                    // expanded
+
+// In the preceeding example, `lvl` doesn't need a lifetime because it's not a
+// reference (`&`). Only things relating to references (such as a `struct`
+// which contains a reference) need lifetimes.
+
+fn substr(s: &str, until: uint) -> &str;                // elided
+fn substr<'a>(s: &'a str, until: uint) -> &'a str;      // expanded
+
+fn get_str() -> &str;                                   // ILLEGAL, no inputs
+
+fn frob(s: &str, t: &str) -> &str;                      // ILLEGAL, two inputs
+
+fn get_mut(&mut self) -> &mut T;                        // elided
+fn get_mut<'a>(&'a mut self) -> &'a mut T;              // expanded
+
+fn args<T:ToCStr>(&mut self, args: &[T]) -> &mut Command                  // elided
+fn args<'a, 'b, T:ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded
+
+fn new(buf: &mut [u8]) -> BufWriter;                    // elided
+fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a>          // expanded
+```
+
 # Related Resources
 
 Coming Soon.
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 4606a1ba846ff82e7a6c1af6bd4b4314849657c1..4c3d93bdfbe5feb70333c8aa1fc7f1b419f66db7 100644 (file)
@@ -503,6 +503,8 @@ Advice on writing benchmarks:
 * Make the code in the `iter` loop do something simple, to assist in pinpointing
   performance improvements (or regressions)
 
+## Gotcha: optimizations
+
 There's another tricky part to writing benchmarks: benchmarks compiled with
 optimizations activated can be dramatically changed by the optimizer so that
 the benchmark is no longer benchmarking what one expects. For example, the
@@ -556,8 +558,12 @@ extern crate test;
 # struct X;
 # impl X { fn iter<T, F>(&self, _: F) where F: FnMut() -> T {} } let b = X;
 b.iter(|| {
-    test::black_box(range(0u, 1000).fold(0, |old, new| old ^ new));
-});
+    let mut n = 1000_u32;
+
+    test::black_box(&mut n); // pretend to modify `n`
+
+    range(0, n).fold(0, |a, b| a ^ b)
+})
 # }
 ```
 
@@ -573,3 +579,6 @@ test bench_xor_1000_ints ... bench:       1 ns/iter (+/- 0)
 
 test result: ok. 0 passed; 0 failed; 0 ignored; 1 measured
 ```
+
+However, the optimizer can still modify a testcase in an undesirable manner
+even when using either of the above.
index e60740db353bca191d1fcd7b588af5be5c654407..66551ec499a89eeb96044251a9b440b9910e46ae 100644 (file)
@@ -355,7 +355,7 @@ Hello, world!
 Bam! We build our project with `cargo build`, and run it with
 `./target/hello_world`. This hasn't bought us a whole lot over our simple use
 of `rustc`, but think about the future: when our project has more than one
-file, we would need to call `rustc` twice, and pass it a bunch of options to
+file, we would need to call `rustc` more than once, and pass it a bunch of options to
 tell it to build everything together. With Cargo, as our project grows, we can
 just `cargo build` and it'll work the right way.
 
@@ -977,7 +977,7 @@ fn main() {
 ```
 
 Even though Rust functions can only return one value, a tuple _is_ one value,
-that happens to be made up of two. You can also see in this example how you
+that happens to be made up of more than one value. You can also see in this example how you
 can destructure a pattern returned by a function, as well.
 
 Tuples are a very simple data structure, and so are not often what you want.
index 5c00993d918d72a9a0d0d56997d4ba64c2eccbaf..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 `$`.)
@@ -1259,8 +1261,8 @@ We call such functions "diverging" because they never return a value to the
 caller. Every control path in a diverging function must end with a `panic!()` or
 a call to another diverging function on every control path. The `!` annotation
 does *not* denote a type. Rather, the result type of a diverging function is a
-special type called $\bot$ ("bottom") that unifies with any type. Rust has no
-syntax for $\bot$.
+special type called  ("bottom") that unifies with any type. Rust has no
+syntax for .
 
 It might be necessary to declare a diverging function because as mentioned
 previously, the typechecker checks that every control path in a function ends
@@ -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
@@ -3484,8 +3490,9 @@ fn main() {
 
 ```
 
-Patterns can also dereference pointers by using the `&`, `box` symbols,
-as appropriate. For example, these two matches on `x: &int` are equivalent:
+Patterns can also dereference pointers by using the `&`, `&mut` and `box`
+symbols, as appropriate. For example, these two matches on `x: &int` are
+equivalent:
 
 ```
 # let x = &3i;
@@ -4316,73 +4323,28 @@ fine-grained control is desired over the output format of a Rust crate.
 
 *TODO*.
 
-# Appendix: Influences and further references
-
-## Influences
-
->  The essential problem that must be solved in making a fault-tolerant
->  software system is therefore that of fault-isolation. Different programmers
->  will write different modules, some modules will be correct, others will have
->  errors. We do not want the errors in one module to adversely affect the
->  behaviour of a module which does not have any errors.
->
->  &mdash; Joe Armstrong
-
->  In our approach, all data is private to some process, and processes can
->  only communicate through communications channels. *Security*, as used
->  in this paper, is the property which guarantees that processes in a system
->  cannot affect each other except by explicit communication.
->
->  When security is absent, nothing which can be proven about a single module
->  in isolation can be guaranteed to hold when that module is embedded in a
->  system [...]
->
->  &mdash; Robert Strom and Shaula Yemini
-
->  Concurrent and applicative programming complement each other. The
->  ability to send messages on channels provides I/O without side effects,
->  while the avoidance of shared data helps keep concurrent processes from
->  colliding.
->
->  &mdash; Rob Pike
-
-Rust is not a particularly original language. It may however appear unusual by
-contemporary standards, as its design elements are drawn from a number of
-"historical" languages that have, with a few exceptions, fallen out of favour.
-Five prominent lineages contribute the most, though their influences have come
-and gone during the course of Rust's development:
-
-* The NIL (1981) and Hermes (1990) family. These languages were developed by
-  Robert Strom, Shaula Yemini, David Bacon and others in their group at IBM
-  Watson Research Center (Yorktown Heights, NY, USA).
-
-* The Erlang (1987) language, developed by Joe Armstrong, Robert Virding, Claes
-  Wikstr&ouml;m, Mike Williams and others in their group at the Ericsson Computer
-  Science Laboratory (&Auml;lvsj&ouml;, Stockholm, Sweden) .
-
-* The Sather (1990) language, developed by Stephen Omohundro, Chu-Cheow Lim,
-  Heinz Schmidt and others in their group at The International Computer
-  Science Institute of the University of California, Berkeley (Berkeley, CA,
-  USA).
-
-* The Newsqueak (1988), Alef (1995), and Limbo (1996) family. These
-  languages were developed by Rob Pike, Phil Winterbottom, Sean Dorward and
-  others in their group at Bell Labs Computing Sciences Research Center
-  (Murray Hill, NJ, USA).
-
-* The Napier (1985) and Napier88 (1988) family. These languages were
-  developed by Malcolm Atkinson, Ron Morrison and others in their group at
-  the University of St. Andrews (St. Andrews, Fife, UK).
-
-Additional specific influences can be seen from the following languages:
-
-* The structural algebraic types and compilation manager of SML.
-* The attribute and assembly systems of C#.
-* The references and deterministic destructor system of C++.
-* The memory region systems of the ML Kit and Cyclone.
-* The typeclass system of Haskell.
-* The lexical identifier rule of Python.
-* The block syntax of Ruby.
+# Appendix: Influences
+
+Rust is not a particularly original language, with design elements coming from
+a wide range of sources. Some of these are listed below (including elements
+that have since been removed):
+
+* SML, OCaml: algebraic datatypes, pattern matching, type inference,
+  semicolon statement separation
+* C++: references, RAII, smart pointers, move semantics, monomorphisation,
+  memory model
+* ML Kit, Cyclone: region based memory management
+* Haskell (GHC): typeclasses, type families
+* Newsqueak, Alef, Limbo: channels, concurrency
+* Erlang: message passing, task failure, ~~linked task failure~~,
+  ~~lightweight concurrency~~
+* Swift: optional bindings
+* Scheme: hygienic macros
+* C#: attributes
+* Ruby: ~~block syntax~~
+* NIL, Hermes: ~~typestate~~
+* [Unicode Annex #31](http://www.unicode.org/reports/tr31/): identifier and
+  pattern syntax
 
 [ffi]: guide-ffi.html
 [plugin]: guide-plugin.html
diff --git a/src/doc/uptack.tex b/src/doc/uptack.tex
new file mode 100644 (file)
index 0000000..32158ea
--- /dev/null
@@ -0,0 +1,2 @@
+\usepackage{newunicodechar}
+\newunicodechar⊥{{$\bot$}}
index 9d0450285091c13703745d94a3ed53a611a3946a..1fb01767a130b4833f0a36031a7ae678c652dbb4 100644 (file)
        <list name="type">
                <item> type </item>
        </list>
+       <list name="reserved">
+               <item> abstract </item>
+               <item> alignof </item>
+               <item> be </item>
+               <item> do </item>
+               <item> final </item>
+               <item> offsetof </item>
+               <item> override </item>
+               <item> priv </item>
+               <item> pure </item>
+               <item> sizeof </item>
+               <item> typeof </item>
+               <item> unsized </item>
+               <item> yield </item>
+       </list>
        <list name="keywords">
                <item> as </item>
-               <item> break </item>
                <item> box </item>
+               <item> break </item>
                <item> const </item>
                <item> continue </item>
                <item> crate </item>
-               <item> do </item>
-               <item> drop </item>
                <item> else </item>
                <item> enum </item>
                <item> extern </item>
                <item> for </item>
                <item> if </item>
                <item> impl </item>
+               <item> in </item>
                <item> let </item>
                <item> loop </item>
                <item> match </item>
                <item> mod </item>
                <item> move </item>
                <item> mut </item>
-               <item> priv </item>
                <item> pub </item>
                <item> ref </item>
                <item> return </item>
                        <DetectSpaces/>
                        <keyword String="fn" attribute="Keyword" context="Function"/>
                        <keyword String="type" attribute="Keyword" context="Type"/>
+                       <keyword String="reserved" attribute="Keyword" context="#stay"/>
                        <keyword String="keywords" attribute="Keyword" context="#stay"/>
                        <keyword String="types" attribute="Type" context="#stay"/>
                        <keyword String="traits" attribute="Trait" context="#stay"/>
index 5588152a244c44c2554192290eedfe53d62a501e..dce6d3f66879e3cca1d93594a22ad555fda3b650 100644 (file)
@@ -3,7 +3,7 @@
 " Maintainer:   Patrick Walton <pcwalton@mozilla.com>
 " Maintainer:   Ben Blum <bblum@cs.cmu.edu>
 " Maintainer:   Chris Morgan <me@chrismorgan.info>
-" Last Change:  July 18, 2014
+" Last Change:  January 5, 2015
 
 if version < 600
   syntax clear
@@ -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
@@ -68,59 +68,37 @@ syn keyword   rustType        f64 i8 i16 i32 i64 str Self
 
 " Reexported core operators {{{3
 syn keyword   rustTrait       Copy Send Sized Sync
-syn keyword   rustTrait       Add Sub Mul Div Rem Neg Not
-syn keyword   rustTrait       BitAnd BitOr BitXor
-syn keyword   rustTrait       Drop Deref DerefMut
-syn keyword   rustTrait       Shl Shr
-syn keyword   rustTrait       Index IndexMut
-syn keyword   rustTrait       Slice SliceMut
-syn keyword   rustTrait       Fn FnMut FnOnce
+syn keyword   rustTrait       Drop Fn FnMut FnOnce
 
 " Reexported functions {{{3
-"syn keyword rustFunction range repeat
-"syn keyword rustFunction drop
-"syn keyword rustFunction from_str
+syn keyword rustFunction drop
 
 " Reexported types and traits {{{3
-syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr
-syn keyword rustTrait IntoBytes
-syn keyword rustTrait ToCStr
-syn keyword rustTrait Char UnicodeChar
+syn keyword rustTrait Box
+syn keyword rustTrait CharExt
 syn keyword rustTrait Clone
 syn keyword rustTrait PartialEq PartialOrd Eq Ord
-syn keyword rustEnum Ordering Equiv
-syn keyword rustEnumVariant Less Equal Greater
-syn keyword rustTrait FromIterator Extend ExactSizeIterator
-syn keyword rustTrait Iterator DoubleEndedIterator
-syn keyword rustTrait RandomAccessIterator CloneableIterator
-syn keyword rustTrait OrdIterator MutableDoubleEndedIterator
-syn keyword rustTrait ToPrimitive FromPrimitive
-syn keyword rustTrait Box
+syn keyword rustTrait DoubleEndedIterator
+syn keyword rustTrait ExactSizeIterator
+syn keyword rustTrait Iterator IteratorExt Extend
 syn keyword rustEnum Option
 syn keyword rustEnumVariant Some None
-syn keyword rustTrait GenericPath Path PosixPath WindowsPath
-syn keyword rustTrait RawPtr RawMutPtr
+syn keyword rustTrait PtrExt MutPtrExt
 syn keyword rustEnum Result
 syn keyword rustEnumVariant Ok Err
-syn keyword rustTrait Buffer Writer Reader Seek BufferPrelude
-syn keyword rustTrait Str StrVector StrPrelude
-syn keyword rustTrait IntoMaybeOwned StrAllocating UnicodeStrPrelude
-syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
-syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
-syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
-syn keyword rustTrait SlicePrelude AsSlice CloneSlicePrelude
-syn keyword rustTrait VectorVector PartialEqSlicePrelude OrdSlicePrelude
-syn keyword rustTrait CloneSliceAllocPrelude OrdSliceAllocPrelude SliceAllocPrelude
-syn keyword rustTrait IntoString String ToString
+syn keyword rustTrait AsSlice
+syn keyword rustTrait SliceExt SliceConcatExt
+syn keyword rustTrait Str StrExt
+syn keyword rustTrait String ToString
 syn keyword rustTrait Vec
-
-" Reexported runtime types {{{3
-"syn keyword rustFunction sync_channel channel
-syn keyword rustTrait SyncSender Sender Receiver
-"syn keyword rustFunction spawn
+" FIXME: remove when path reform lands
+syn keyword rustTrait Path GenericPath
+" FIXME: remove when I/O reform lands
+syn keyword rustTrait Buffer Writer Reader Seek BufferPrelude
+" FIXME: remove when range syntax lands
+syn keyword rustFunction range
 
 " Other syntax {{{2
-
 syn keyword   rustSelf        self
 syn keyword   rustBoolean     true false
 
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 88f02d6573eac788f930391f1c393873cb7b1c52..25f80ad11bd1124b87ef34445b799b4dd67f80cf 100644 (file)
@@ -246,7 +246,7 @@ fn borrow_from(owned: &Arc<T>) -> &T {
     }
 }
 
-#[experimental = "Deref is experimental."]
+#[stable]
 impl<T> Deref for Arc<T> {
     type Target = T;
 
@@ -290,7 +290,7 @@ pub fn make_unique(&mut self) -> &mut T {
 }
 
 #[unsafe_destructor]
-#[experimental = "waiting on stability of Drop"]
+#[stable]
 impl<T: Sync + Send> Drop for Arc<T> {
     /// Drops the `Arc<T>`.
     ///
@@ -418,7 +418,7 @@ fn clone(&self) -> Weak<T> {
 }
 
 #[unsafe_destructor]
-#[experimental = "Weak pointers may not belong in this module."]
+#[stable]
 impl<T: Sync + Send> Drop for Weak<T> {
     /// Drops the `Weak<T>`.
     ///
index 2c318181b099521fc88e0f9f54c15da0dbc12b77..6df8bb5f7aaf4b146b76b88ea00850932c17b7e3 100644 (file)
@@ -75,14 +75,14 @@ fn clone_from(&mut self, source: &Box<T>) {
 }
 
 #[stable]
-impl<Sized? T: PartialEq> PartialEq for Box<T> {
+impl<T: ?Sized + PartialEq> PartialEq for Box<T> {
     #[inline]
     fn eq(&self, other: &Box<T>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
     fn ne(&self, other: &Box<T>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 #[stable]
-impl<Sized? T: PartialOrd> PartialOrd for Box<T> {
+impl<T: ?Sized + PartialOrd> PartialOrd for Box<T> {
     #[inline]
     fn partial_cmp(&self, other: &Box<T>) -> Option<Ordering> {
         PartialOrd::partial_cmp(&**self, &**other)
@@ -97,16 +97,16 @@ fn ge(&self, other: &Box<T>) -> bool { PartialOrd::ge(&**self, &**other) }
     fn gt(&self, other: &Box<T>) -> bool { PartialOrd::gt(&**self, &**other) }
 }
 #[stable]
-impl<Sized? T: Ord> Ord for Box<T> {
+impl<T: ?Sized + Ord> Ord for Box<T> {
     #[inline]
     fn cmp(&self, other: &Box<T>) -> Ordering {
         Ord::cmp(&**self, &**other)
     }
 
 #[stable]}
-impl<Sized? T: Eq> Eq for Box<T> {}
+impl<T: ?Sized + Eq> Eq for Box<T> {}
 
-impl<S: hash::Writer, Sized? T: Hash<S>> Hash<S> for Box<T> {
+impl<S: hash::Writer, T: ?Sized + Hash<S>> Hash<S> for Box<T> {
     #[inline]
     fn hash(&self, state: &mut S) {
         (**self).hash(state);
@@ -143,7 +143,7 @@ fn downcast<T: 'static>(self) -> Result<Box<T>, Box<Any>> {
     }
 }
 
-impl<Sized? T: fmt::Show> fmt::Show for Box<T> {
+impl<T: ?Sized + fmt::Show> fmt::Show for Box<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         (**self).fmt(f)
     }
@@ -155,13 +155,15 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-impl<Sized? T> Deref for Box<T> {
+#[stable]
+impl<T: ?Sized> Deref for Box<T> {
     type Target = T;
 
     fn deref(&self) -> &T { &**self }
 }
 
-impl<Sized? T> DerefMut for Box<T> {
+#[stable]
+impl<T: ?Sized> DerefMut for Box<T> {
     fn deref_mut(&mut self) -> &mut T { &mut **self }
 }
 
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 c4b455aff5c53cea59eecc9ff87489e29bb1d731..175bba4e71dc46f9671f04658e5a3b034914a43e 100644 (file)
@@ -354,7 +354,7 @@ fn borrow_from(owned: &Rc<T>) -> &T {
     }
 }
 
-#[experimental = "Deref is experimental."]
+#[stable]
 impl<T> Deref for Rc<T> {
     type Target = T;
 
@@ -365,7 +365,7 @@ fn deref(&self) -> &T {
 }
 
 #[unsafe_destructor]
-#[experimental = "Drop is experimental."]
+#[stable]
 impl<T> Drop for Rc<T> {
     /// Drops the `Rc<T>`.
     ///
@@ -656,7 +656,7 @@ pub fn upgrade(&self) -> Option<Rc<T>> {
 }
 
 #[unsafe_destructor]
-#[experimental = "Weak pointers may not belong in this module."]
+#[stable]
 impl<T> Drop for Weak<T> {
     /// Drops the `Weak<T>`.
     ///
index 4a550e5ce277d5eb7b1f8267bb567f9a72b02e6d..01693391abed51037186c9f781eca4141ae148b9 100644 (file)
 //! ```
 
 #![allow(missing_docs)]
+#![stable]
 
 use core::prelude::*;
 
@@ -561,11 +562,13 @@ pub fn drain(&mut self) -> Drain<T> {
 }
 
 /// `BinaryHeap` iterator.
+#[stable]
 pub struct Iter <'a, T: 'a> {
     iter: slice::Iter<'a, T>,
 }
 
 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+#[stable]
 impl<'a, T> Clone for Iter<'a, T> {
     fn clone(&self) -> Iter<'a, T> {
         Iter { iter: self.iter.clone() }
@@ -593,6 +596,7 @@ fn next_back(&mut self) -> Option<&'a T> { self.iter.next_back() }
 impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
 
 /// An iterator that moves out of a `BinaryHeap`.
+#[stable]
 pub struct IntoIter<T> {
     iter: vec::IntoIter<T>,
 }
@@ -618,6 +622,7 @@ fn next_back(&mut self) -> Option<T> { self.iter.next_back() }
 impl<T> ExactSizeIterator for IntoIter<T> {}
 
 /// An iterator that drains a `BinaryHeap`.
+#[unstable = "recent addition"]
 pub struct Drain<'a, T: 'a> {
     iter: vec::Drain<'a, T>,
 }
index ea504530c4b21309b2660a5f1449c29742b855fe..b85ea65f5ce5880140611f8be2d09687be61c5d0 100644 (file)
@@ -130,7 +130,7 @@ pub struct Values<'a, K: 'a, V: 'a> {
 
 #[stable]
 /// A view into a single entry in a map, which may either be vacant or occupied.
-pub enum Entry<'a, Sized? Q:'a, K:'a, V:'a> {
+pub enum Entry<'a, Q: ?Sized +'a, K:'a, V:'a> {
     /// A vacant Entry
     Vacant(VacantEntry<'a, Q, K, V>),
     /// An occupied Entry
@@ -139,7 +139,7 @@ pub enum Entry<'a, Sized? Q:'a, K:'a, V:'a> {
 
 #[stable]
 /// A vacant Entry.
-pub struct VacantEntry<'a, Sized? Q:'a, K:'a, V:'a> {
+pub struct VacantEntry<'a, Q: ?Sized +'a, K:'a, V:'a> {
     key: &'a Q,
     stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>,
 }
@@ -214,7 +214,7 @@ pub fn clear(&mut self) {
     /// assert_eq!(map.get(&2), None);
     /// ```
     #[stable]
-    pub fn get<Sized? Q>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord {
+    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord {
         let mut cur_node = &self.root;
         loop {
             match Node::search(cur_node, key) {
@@ -246,7 +246,7 @@ pub fn get<Sized? Q>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord
     /// assert_eq!(map.contains_key(&2), false);
     /// ```
     #[stable]
-    pub fn contains_key<Sized? Q>(&self, key: &Q) -> bool where Q: BorrowFrom<K> + Ord {
+    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where Q: BorrowFrom<K> + Ord {
         self.get(key).is_some()
     }
 
@@ -270,7 +270,7 @@ pub fn contains_key<Sized? Q>(&self, key: &Q) -> bool where Q: BorrowFrom<K> + O
     /// ```
     // See `get` for implementation notes, this is basically a copy-paste with mut's added
     #[stable]
-    pub fn get_mut<Sized? Q>(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom<K> + Ord {
+    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom<K> + Ord {
         // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration
         let mut temp_node = &mut self.root;
         loop {
@@ -440,7 +440,7 @@ pub fn insert(&mut self, mut key: K, mut value: V) -> Option<V> {
     /// assert_eq!(map.remove(&1), None);
     /// ```
     #[stable]
-    pub fn remove<Sized? Q>(&mut self, key: &Q) -> Option<V> where Q: BorrowFrom<K> + Ord {
+    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where Q: BorrowFrom<K> + Ord {
         // See `swap` for a more thorough description of the stuff going on in here
         let mut stack = stack::PartialSearchStack::new(self);
         loop {
@@ -878,7 +878,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 }
 
 #[stable]
-impl<K: Ord, Sized? Q, V> Index<Q> for BTreeMap<K, V>
+impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
     where Q: BorrowFrom<K> + Ord
 {
     type Output = V;
@@ -889,7 +889,7 @@ fn index(&self, key: &Q) -> &V {
 }
 
 #[stable]
-impl<K: Ord, Sized? Q, V> IndexMut<Q> for BTreeMap<K, V>
+impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
     where Q: BorrowFrom<K> + Ord
 {
     type Output = V;
@@ -1111,7 +1111,7 @@ fn next_back(&mut self) -> Option<(&'a V)> { self.inner.next_back() }
 #[stable]
 impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}
 
-impl<'a, Sized? Q, K: Ord, V> Entry<'a, Q, K, V> {
+impl<'a, Q: ?Sized, K: Ord, V> Entry<'a, Q, K, V> {
     #[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
     /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
     pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, Q, K, V>> {
@@ -1122,7 +1122,7 @@ pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, Q, K, V>> {
     }
 }
 
-impl<'a, Sized? Q: ToOwned<K>, K: Ord, V> VacantEntry<'a, Q, K, V> {
+impl<'a, Q: ?Sized + ToOwned<K>, K: Ord, V> VacantEntry<'a, Q, K, V> {
     #[stable]
     /// Sets the value of the entry with the VacantEntry's key,
     /// and returns a mutable reference to it.
@@ -1362,7 +1362,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// ```
     /// The key must have the same ordering before or after `.to_owned()` is called.
     #[stable]
-    pub fn entry<'a, Sized? Q>(&'a mut self, mut key: &'a Q) -> Entry<'a, Q, K, V>
+    pub fn entry<'a, Q: ?Sized>(&'a mut self, mut key: &'a Q) -> Entry<'a, Q, K, V>
         where Q: Ord + ToOwned<K>
     {
         // same basic logic of `swap` and `pop`, blended together
index 1f719da590b349b8e772e26d4ef924e9008d0759..0a93bbf89c9971dea74fe7c5fadc95e614f35f06 100644 (file)
@@ -517,7 +517,7 @@ impl<K: Ord, V> Node<K, V> {
     /// Searches for the given key in the node. If it finds an exact match,
     /// `Found` will be yielded with the matching index. If it doesn't find an exact match,
     /// `GoDown` will be yielded with the index of the subtree the key must lie in.
-    pub fn search<Sized? Q, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key: &Q)
+    pub fn search<Q: ?Sized, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key: &Q)
                   -> SearchResult<NodeRef> where Q: BorrowFrom<K> + Ord {
         // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V).
         // For the B configured as of this writing (B = 6), binary search was *significantly*
@@ -536,7 +536,7 @@ pub fn search<Sized? Q, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key: &
         }
     }
 
-    fn search_linear<Sized? Q>(&self, key: &Q) -> (bool, uint) where Q: BorrowFrom<K> + Ord {
+    fn search_linear<Q: ?Sized>(&self, key: &Q) -> (bool, uint) where Q: BorrowFrom<K> + Ord {
         for (i, k) in self.keys().iter().enumerate() {
             match key.cmp(BorrowFrom::borrow_from(k)) {
                 Greater => {},
index 0406edcdd32e7ac622bbb277544f63120df93e93..98f163321706041f81f7fb731f81726ba79b1303 100644 (file)
@@ -299,7 +299,7 @@ pub fn clear(&mut self) {
     /// assert_eq!(set.contains(&4), false);
     /// ```
     #[stable]
-    pub fn contains<Sized? Q>(&self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
+    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
         self.map.contains_key(value)
     }
 
@@ -429,7 +429,7 @@ pub fn insert(&mut self, value: T) -> bool {
     /// assert_eq!(set.remove(&2), false);
     /// ```
     #[stable]
-    pub fn remove<Sized? Q>(&mut self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
+    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
         self.map.remove(value).is_some()
     }
 }
index ca8e75ac43c8d6f84ebe1f3d6331b2b3d251e542..5e08f90ce1c536368aef61df7e5577e675932a1e 100644 (file)
@@ -19,6 +19,8 @@
 // Backlinks over DList::prev are raw pointers that form a full chain in
 // the reverse direction.
 
+#![stable]
+
 use core::prelude::*;
 
 use alloc::boxed::Box;
@@ -1064,6 +1066,7 @@ fn fuzz_test(sz: int) {
     }
 
     #[allow(deprecated)]
+    #[test]
     fn test_append() {
         {
             let mut m = DList::new();
index db2367950387b4a125d74446770a90fb07e6dc35..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;
 pub mod vec;
 pub mod vec_map;
 
+#[stable]
 pub mod bitv {
     pub use bit::{Bitv, Iter};
 }
 
+#[stable]
 pub mod bitv_set {
     pub use bit::{BitvSet, Union, Intersection, Difference, SymmetricDifference};
     pub use bit::SetIter as Iter;
 }
 
+#[stable]
 pub mod btree_map {
     pub use btree::map::*;
 }
 
+#[stable]
 pub mod btree_set {
     pub use btree::set::*;
 }
@@ -109,8 +137,7 @@ mod prelude {
     pub use core::iter::range;
     pub use core::iter::{FromIterator, Extend, IteratorExt};
     pub use core::iter::{Iterator, DoubleEndedIterator, RandomAccessIterator};
-    pub use core::iter::{IteratorCloneExt, CloneIteratorExt};
-    pub use core::iter::{IteratorOrdExt, MutableDoubleEndedIterator, ExactSizeIterator};
+    pub use core::iter::{ExactSizeIterator};
     pub use core::kinds::{Copy, Send, Sized, Sync};
     pub use core::mem::drop;
     pub use core::ops::{Drop, Fn, FnMut, FnOnce};
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 ce9643b3b439199b30f7866e9d24dec588134677..11775f62b1c547660826fcef88d1164d00cdf0be 100644 (file)
 //! ends of the container. It also has `O(1)` indexing like a vector. The contained elements are
 //! not required to be copyable, and the queue will be sendable if the contained type is sendable.
 
+#![stable]
+
 use core::prelude::*;
 
 use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt;
-use core::iter::{self, FromIterator, RandomAccessIterator};
+use core::iter::{self, repeat, FromIterator, RandomAccessIterator};
 use core::kinds::marker;
 use core::mem;
 use core::num::{Int, UnsignedInt};
 
 use alloc::heap;
 
-static INITIAL_CAPACITY: uint = 8u; // 2^3
-static MINIMUM_CAPACITY: uint = 2u;
-
-// FIXME(conventions): implement shrink_to_fit. Awkward with the current design, but it should
-// be scrapped anyway. Defer to rewrite?
+static INITIAL_CAPACITY: uint = 7u; // 2^3 - 1
+static MINIMUM_CAPACITY: uint = 1u; // 2 - 1
 
 /// `RingBuf` is a circular buffer, which can be used as a double-ended queue efficiently.
 #[stable]
@@ -127,7 +126,20 @@ unsafe fn copy(&self, dst: uint, src: uint, len: uint) {
                       self.cap);
         ptr::copy_memory(
             self.ptr.offset(dst as int),
-            self.ptr.offset(src as int) as *const T,
+            self.ptr.offset(src as int),
+            len);
+    }
+
+    /// Copies a contiguous block of memory len long from src to dst
+    #[inline]
+    unsafe fn copy_nonoverlapping(&self, dst: uint, src: uint, len: uint) {
+        debug_assert!(dst + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
+                      self.cap);
+        debug_assert!(src + len <= self.cap, "dst={} src={} len={} cap={}", dst, src, len,
+                      self.cap);
+        ptr::copy_nonoverlapping_memory(
+            self.ptr.offset(dst as int),
+            self.ptr.offset(src as int),
             len);
     }
 }
@@ -143,7 +155,8 @@ pub fn new() -> RingBuf<T> {
     #[stable]
     pub fn with_capacity(n: uint) -> RingBuf<T> {
         // +1 since the ringbuffer always leaves one space empty
-        let cap = cmp::max(n + 1, MINIMUM_CAPACITY).next_power_of_two();
+        let cap = cmp::max(n + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
+        assert!(cap > n, "capacity overflow");
         let size = cap.checked_mul(mem::size_of::<T>())
                       .expect("capacity overflow");
 
@@ -346,31 +359,134 @@ pub fn reserve(&mut self, additional: uint) {
                 // Nop
             } else if self.head < oldcap - self.tail { // B
                 unsafe {
-                    ptr::copy_nonoverlapping_memory(
-                        self.ptr.offset(oldcap as int),
-                        self.ptr as *const T,
-                        self.head
-                    );
+                    self.copy_nonoverlapping(oldcap, 0, self.head);
                 }
                 self.head += oldcap;
                 debug_assert!(self.head > self.tail);
             } else { // C
+                let new_tail = count - (oldcap - self.tail);
+                unsafe {
+                    self.copy_nonoverlapping(new_tail, self.tail, oldcap - self.tail);
+                }
+                self.tail = new_tail;
+                debug_assert!(self.head < self.tail);
+            }
+            debug_assert!(self.head < self.cap);
+            debug_assert!(self.tail < self.cap);
+            debug_assert!(self.cap.count_ones() == 1);
+        }
+    }
+
+    /// Shrinks the capacity of the ringbuf as much as possible.
+    ///
+    /// It will drop down as close as possible to the length but the allocator may still inform the
+    /// ringbuf that there is space for a few more elements.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut buf = RingBuf::with_capacity(15);
+    /// buf.extend(range(0u, 4));
+    /// assert_eq!(buf.capacity(), 15);
+    /// buf.shrink_to_fit();
+    /// assert!(buf.capacity() >= 4);
+    /// ```
+    pub fn shrink_to_fit(&mut self) {
+        // +1 since the ringbuffer always leaves one space empty
+        // len + 1 can't overflow for an existing, well-formed ringbuf.
+        let target_cap = cmp::max(self.len() + 1, MINIMUM_CAPACITY + 1).next_power_of_two();
+        if target_cap < self.cap {
+            // There are three cases of interest:
+            //   All elements are out of desired bounds
+            //   Elements are contiguous, and head is out of desired bounds
+            //   Elements are discontiguous, and tail is out of desired bounds
+            //
+            // At all other times, element positions are unaffected.
+            //
+            // Indicates that elements at the head should be moved.
+            let head_outside = self.head == 0 || self.head >= target_cap;
+            // Move elements from out of desired bounds (positions after target_cap)
+            if self.tail >= target_cap && head_outside {
+                //                    T             H
+                //   [. . . . . . . . o o o o o o o . ]
+                //    T             H
+                //   [o o o o o o o . ]
+                unsafe {
+                    self.copy_nonoverlapping(0, self.tail, self.len());
+                }
+                self.head = self.len();
+                self.tail = 0;
+            } else if self.tail != 0 && self.tail < target_cap && head_outside {
+                //          T             H
+                //   [. . . o o o o o o o . . . . . . ]
+                //        H T
+                //   [o o . o o o o o ]
+                let len = self.wrap_index(self.head - target_cap);
+                unsafe {
+                    self.copy_nonoverlapping(0, target_cap, len);
+                }
+                self.head = len;
+                debug_assert!(self.head < self.tail);
+            } else if self.tail >= target_cap {
+                //              H                 T
+                //   [o o o o o . . . . . . . . . o o ]
+                //              H T
+                //   [o o o o o . o o ]
+                debug_assert!(self.wrap_index(self.head - 1) < target_cap);
+                let len = self.cap - self.tail;
+                let new_tail = target_cap - len;
                 unsafe {
-                    ptr::copy_nonoverlapping_memory(
-                        self.ptr.offset((count - (oldcap - self.tail)) as int),
-                        self.ptr.offset(self.tail as int) as *const T,
-                        oldcap - self.tail
-                    );
+                    self.copy_nonoverlapping(new_tail, self.tail, len);
                 }
-                self.tail = count - (oldcap - self.tail);
+                self.tail = new_tail;
                 debug_assert!(self.head < self.tail);
             }
+
+            if mem::size_of::<T>() != 0 {
+                let old = self.cap * mem::size_of::<T>();
+                let new_size = target_cap * mem::size_of::<T>();
+                unsafe {
+                    self.ptr = heap::reallocate(self.ptr as *mut u8,
+                                                old,
+                                                new_size,
+                                                mem::min_align_of::<T>()) as *mut T;
+                    if self.ptr.is_null() { ::alloc::oom() }
+                }
+            }
+            self.cap = target_cap;
             debug_assert!(self.head < self.cap);
             debug_assert!(self.tail < self.cap);
             debug_assert!(self.cap.count_ones() == 1);
         }
     }
 
+    /// Shorten a ringbuf, dropping excess elements from the back.
+    ///
+    /// If `len` is greater than the ringbuf's current length, this has no
+    /// effect.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut buf = RingBuf::new();
+    /// buf.push_back(5i);
+    /// buf.push_back(10i);
+    /// buf.push_back(15);
+    /// buf.truncate(1);
+    /// assert_eq!(buf.len(), 1);
+    /// assert_eq!(Some(&5), buf.get(0));
+    /// ```
+    #[unstable = "matches collection reform specification; waiting on panic semantics"]
+    pub fn truncate(&mut self, len: uint) {
+        for _ in range(len, self.len()) {
+            self.pop_back();
+        }
+    }
+
     /// Returns a front-to-back iterator.
     ///
     /// # Examples
@@ -735,6 +851,70 @@ fn is_contiguous(&self) -> bool {
         self.tail <= self.head
     }
 
+    /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the last
+    /// element.
+    ///
+    /// This does not preserve ordering, but is O(1).
+    ///
+    /// Returns `None` if `index` is out of bounds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut buf = RingBuf::new();
+    /// assert_eq!(buf.swap_back_remove(0), None);
+    /// buf.push_back(5i);
+    /// buf.push_back(99);
+    /// buf.push_back(15);
+    /// buf.push_back(20);
+    /// buf.push_back(10);
+    /// assert_eq!(buf.swap_back_remove(1), Some(99));
+    /// ```
+    #[unstable = "the naming of this function may be altered"]
+    pub fn swap_back_remove(&mut self, index: uint) -> Option<T> {
+        let length = self.len();
+        if length > 0 && index < length - 1 {
+            self.swap(index, length - 1);
+        } else if index >= length {
+            return None;
+        }
+        self.pop_back()
+    }
+
+    /// Removes an element from anywhere in the ringbuf and returns it, replacing it with the first
+    /// element.
+    ///
+    /// This does not preserve ordering, but is O(1).
+    ///
+    /// Returns `None` if `index` is out of bounds.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut buf = RingBuf::new();
+    /// assert_eq!(buf.swap_front_remove(0), None);
+    /// buf.push_back(15i);
+    /// buf.push_back(5);
+    /// buf.push_back(10);
+    /// buf.push_back(99);
+    /// buf.push_back(20i);
+    /// assert_eq!(buf.swap_front_remove(3), Some(99));
+    /// ```
+    #[unstable = "the naming of this function may be altered"]
+    pub fn swap_front_remove(&mut self, index: uint) -> Option<T> {
+        let length = self.len();
+        if length > 0 && index < length && index != 0 {
+            self.swap(index, 0);
+        } else if index >= length {
+            return None;
+        }
+        self.pop_front()
+    }
+
     /// Inserts an element at position `i` within the ringbuf. Whichever
     /// end is closer to the insertion point will be moved to make room,
     /// and all the affected elements will be moved to new positions.
@@ -743,7 +923,7 @@ fn is_contiguous(&self) -> bool {
     ///
     /// Panics if `i` is greater than ringbuf's length
     ///
-    /// # Example
+    /// # Examples
     /// ```rust
     /// use std::collections::RingBuf;
     ///
@@ -945,7 +1125,7 @@ pub fn insert(&mut self, i: uint, t: T) {
     /// room, and all the affected elements will be moved to new positions.
     /// Returns `None` if `i` is out of bounds.
     ///
-    /// # Example
+    /// # Examples
     /// ```rust
     /// use std::collections::RingBuf;
     ///
@@ -990,7 +1170,7 @@ pub fn remove(&mut self, i: uint) -> Option<T> {
         let distance_to_tail = i;
         let distance_to_head = self.len() - i;
 
-        let contiguous = self.tail <= self.head;
+        let contiguous = self.is_contiguous();
 
         match (contiguous, distance_to_tail <= distance_to_head, idx >= self.tail) {
             (true, true, _) => unsafe {
@@ -1105,6 +1285,37 @@ pub fn remove(&mut self, i: uint) -> Option<T> {
     }
 }
 
+impl<T: Clone> RingBuf<T> {
+    /// Modifies the ringbuf in-place so that `len()` is equal to new_len,
+    /// either by removing excess elements or by appending copies of a value to the back.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut buf = RingBuf::new();
+    /// buf.push_back(5i);
+    /// buf.push_back(10i);
+    /// buf.push_back(15);
+    /// buf.resize(2, 0);
+    /// buf.resize(6, 20);
+    /// for (a, b) in [5, 10, 20, 20, 20, 20].iter().zip(buf.iter()) {
+    ///     assert_eq!(a, b);
+    /// }
+    /// ```
+    #[unstable = "matches collection reform specification; waiting on panic semantics"]
+    pub fn resize(&mut self, new_len: uint, value: T) {
+        let len = self.len();
+
+        if new_len > len {
+            self.extend(repeat(value).take(new_len - len))
+        } else {
+            self.truncate(new_len);
+        }
+    }
+}
+
 /// Returns the index in the underlying buffer for a given logical element index.
 #[inline]
 fn wrap_index(index: uint, size: uint) -> uint {
@@ -2270,6 +2481,50 @@ fn test_get_mut() {
         assert_eq!(ring.get_mut(2), None);
     }
 
+    #[test]
+    fn test_swap_front_back_remove() {
+        fn test(back: bool) {
+            // This test checks that every single combination of tail position and length is tested.
+            // Capacity 15 should be large enough to cover every case.
+            let mut tester = RingBuf::with_capacity(15);
+            let usable_cap = tester.capacity();
+            let final_len = usable_cap / 2;
+
+            for len in range(0, final_len) {
+                let expected = if back {
+                    range(0, len).collect()
+                } else {
+                    range(0, len).rev().collect()
+                };
+                for tail_pos in range(0, usable_cap) {
+                    tester.tail = tail_pos;
+                    tester.head = tail_pos;
+                    if back {
+                        for i in range(0, len * 2) {
+                            tester.push_front(i);
+                        }
+                        for i in range(0, len) {
+                            assert_eq!(tester.swap_back_remove(i), Some(len * 2 - 1 - i));
+                        }
+                    } else {
+                        for i in range(0, len * 2) {
+                            tester.push_back(i);
+                        }
+                        for i in range(0, len) {
+                            let idx = tester.len() - 1 - i;
+                            assert_eq!(tester.swap_front_remove(idx), Some(len * 2 - 1 - i));
+                        }
+                    }
+                    assert!(tester.tail < tester.cap);
+                    assert!(tester.head < tester.cap);
+                    assert_eq!(tester, expected);
+                }
+            }
+        }
+        test(true);
+        test(false);
+    }
+
     #[test]
     fn test_insert() {
         // This test checks that every single combination of tail position, length, and
@@ -2341,6 +2596,38 @@ fn test_remove() {
         }
     }
 
+    #[test]
+    fn test_shrink_to_fit() {
+        // This test checks that every single combination of head and tail position,
+        // is tested. Capacity 15 should be large enough to cover every case.
+
+        let mut tester = RingBuf::with_capacity(15);
+        // can't guarantee we got 15, so have to get what we got.
+        // 15 would be great, but we will definitely get 2^k - 1, for k >= 4, or else
+        // this test isn't covering what it wants to
+        let cap = tester.capacity();
+        tester.reserve(63);
+        let max_cap = tester.capacity();
+
+        for len in range(0, cap + 1) {
+            // 0, 1, 2, .., len - 1
+            let expected = iter::count(0, 1).take(len).collect();
+            for tail_pos in range(0, max_cap + 1) {
+                tester.tail = tail_pos;
+                tester.head = tail_pos;
+                tester.reserve(63);
+                for i in range(0, len) {
+                    tester.push_back(i);
+                }
+                tester.shrink_to_fit();
+                assert!(tester.capacity() <= cap);
+                assert!(tester.tail < tester.cap);
+                assert!(tester.head < tester.cap);
+                assert_eq!(tester, expected);
+            }
+        }
+    }
+
     #[test]
     fn test_front() {
         let mut ring = RingBuf::new();
index 3602bfc10c3079b5b67a5914a7074b9c465f8c48..9e5aa7d645ba0ac8783b745add1fd592013dbe88 100644 (file)
@@ -86,6 +86,7 @@
 //! * Further iterators exist that split, chunk or permute the slice.
 
 #![doc(primitive = "slice")]
+#![stable]
 
 use alloc::boxed::Box;
 use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
 ////////////////////////////////////////////////////////////////////////////////
 
 /// Allocating extension methods for slices.
-#[unstable = "needs associated types, may merge with other traits"]
-pub trait SliceExt for Sized? {
+#[stable]
+pub trait SliceExt {
+    #[stable]
     type Item;
 
     /// Sorts the slice, in place, using `compare` to compare
@@ -699,7 +701,7 @@ fn binary_search_elem(&self, x: &Self::Item) -> Result<uint, uint> where Self::I
     fn into_vec(self: Box<Self>) -> Vec<Self::Item>;
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<T> SliceExt for [T] {
     type Item = T;
 
@@ -989,7 +991,7 @@ fn into_vec(mut self: Box<Self>) -> Vec<T> {
 ////////////////////////////////////////////////////////////////////////////////
 #[unstable = "U should be an associated type"]
 /// An extension trait for concatenating slices
-pub trait SliceConcatExt<Sized? T, U> for Sized? {
+pub trait SliceConcatExt<T: ?Sized, U> {
     /// Flattens a slice of `T` into a single value `U`.
     #[stable]
     fn concat(&self) -> U;
@@ -1090,6 +1092,7 @@ struct SizeDirection {
     dir: Direction,
 }
 
+#[stable]
 impl Iterator for ElementSwaps {
     type Item = (uint, uint);
 
@@ -2460,13 +2463,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]");
@@ -2486,12 +2489,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 ecf17820d2d8f72c58f44bc97d18c59a3b8666e9..c0482702ccdb66c1a6ee149ebaa0811d7a66808b 100644 (file)
@@ -50,6 +50,7 @@
 //! is the same as `&[u8]`.
 
 #![doc(primitive = "str")]
+#![stable]
 
 use self::RecompositionState::*;
 use self::DecompositionType::*;
@@ -59,7 +60,6 @@
 use core::clone::Clone;
 use core::iter::AdditiveIterator;
 use core::iter::{range, Iterator, IteratorExt};
-use core::kinds::Sized;
 use core::ops;
 use core::option::Option::{self, Some, None};
 use core::slice::AsSlice;
@@ -165,6 +165,7 @@ enum DecompositionType {
 /// External iterator for a string's decomposition's characters.
 /// Use with the `std::iter` module.
 #[derive(Clone)]
+#[unstable]
 pub struct Decompositions<'a> {
     kind: DecompositionType,
     iter: Chars<'a>,
@@ -172,6 +173,7 @@ pub struct Decompositions<'a> {
     sorted: bool
 }
 
+#[stable]
 impl<'a> Iterator for Decompositions<'a> {
     type Item = char;
 
@@ -253,6 +255,7 @@ enum RecompositionState {
 /// External iterator for a string's recomposition's characters.
 /// Use with the `std::iter` module.
 #[derive(Clone)]
+#[unstable]
 pub struct Recompositions<'a> {
     iter: Decompositions<'a>,
     state: RecompositionState,
@@ -261,6 +264,7 @@ pub struct Recompositions<'a> {
     last_ccc: Option<u8>
 }
 
+#[stable]
 impl<'a> Iterator for Recompositions<'a> {
     type Item = char;
 
@@ -348,10 +352,12 @@ fn next(&mut self) -> Option<char> {
 /// External iterator for a string's UTF16 codeunits.
 /// Use with the `std::iter` module.
 #[derive(Clone)]
+#[unstable]
 pub struct Utf16Units<'a> {
     encoder: Utf16Encoder<Chars<'a>>
 }
 
+#[stable]
 impl<'a> Iterator for Utf16Units<'a> {
     type Item = u16;
 
@@ -401,7 +407,8 @@ fn to_owned(&self) -> String {
 */
 
 /// Any string that can be represented as a slice.
-pub trait StrExt for Sized?: ops::Slice<uint, str> {
+#[stable]
+pub trait StrExt: ops::Slice<uint, str> {
     /// Escapes each char in `s` with `char::escape_default`.
     #[unstable = "return type may change to be an iterator"]
     fn escape_default(&self) -> String {
@@ -1340,6 +1347,7 @@ fn trim_right(&self) -> &str {
     }
 }
 
+#[stable]
 impl StrExt for str {}
 
 #[cfg(test)]
@@ -1838,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],
@@ -1858,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 e7451331908aed9e8fdf2fefb3ed60790b63e9dc..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
@@ -320,30 +320,6 @@ pub unsafe fn from_raw_parts(buf: *mut u8, length: uint, capacity: uint) -> Stri
         }
     }
 
-    /// Creates a `String` from a null-terminated `*const u8` buffer.
-    ///
-    /// This function is unsafe because we dereference memory until we find the
-    /// NUL character, which is not guaranteed to be present. Additionally, the
-    /// slice is not checked to see whether it contains valid UTF-8
-    #[unstable = "just renamed from `mod raw`"]
-    pub unsafe fn from_raw_buf(buf: *const u8) -> String {
-        String::from_str(str::from_c_str(buf as *const i8))
-    }
-
-    /// Creates a `String` from a `*const u8` buffer of the given length.
-    ///
-    /// This function is unsafe because it blindly assumes the validity of the
-    /// pointer `buf` for `len` bytes of memory. This function will copy the
-    /// memory from `buf` into a new allocation (owned by the returned
-    /// `String`).
-    ///
-    /// This function is also unsafe because it does not validate that the
-    /// buffer is valid UTF-8 encoded data.
-    #[unstable = "just renamed from `mod raw`"]
-    pub unsafe fn from_raw_buf_len(buf: *const u8, len: uint) -> String {
-        String::from_utf8_unchecked(Vec::from_raw_buf(buf, len))
-    }
-
     /// Converts a vector of bytes to a new `String` without checking if
     /// it contains valid UTF-8. This is unsafe because it assumes that
     /// the UTF-8-ness of the vector has already been validated.
@@ -711,7 +687,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-#[experimental = "waiting on FromIterator stabilization"]
+#[stable]
 impl FromIterator<char> for String {
     fn from_iter<I:Iterator<Item=char>>(iterator: I) -> String {
         let mut buf = String::new();
@@ -720,7 +696,7 @@ fn from_iter<I:Iterator<Item=char>>(iterator: I) -> String {
     }
 }
 
-#[experimental = "waiting on FromIterator stabilization"]
+#[stable]
 impl<'a> FromIterator<&'a str> for String {
     fn from_iter<I:Iterator<Item=&'a str>>(iterator: I) -> String {
         let mut buf = String::new();
@@ -832,7 +808,7 @@ fn hash(&self, hasher: &mut H) {
     }
 }
 
-#[experimental = "waiting on Add stabilization"]
+#[unstable = "recent addition, needs more experience"]
 impl<'a> Add<&'a str> for String {
     type Output = String;
 
@@ -864,7 +840,7 @@ fn slice_or_fail<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
     }
 }
 
-#[experimental = "waiting on Deref stabilization"]
+#[stable]
 impl ops::Deref for String {
     type Target = str;
 
@@ -1126,24 +1102,6 @@ fn test_from_utf16_lossy() {
                    String::from_str("\u{FFFD}𐒋\u{FFFD}"));
     }
 
-    #[test]
-    fn test_from_buf_len() {
-        unsafe {
-            let a = vec![65u8, 65, 65, 65, 65, 65, 65, 0];
-            assert_eq!(String::from_raw_buf_len(a.as_ptr(), 3), String::from_str("AAA"));
-        }
-    }
-
-    #[test]
-    fn test_from_buf() {
-        unsafe {
-            let a = vec![65, 65, 65, 65, 65, 65, 65, 0];
-            let b = a.as_ptr();
-            let c = String::from_raw_buf(b);
-            assert_eq!(c, String::from_str("AAAAAAA"));
-        }
-    }
-
     #[test]
     fn test_push_bytes() {
         let mut s = String::from_str("ABC");
index 4e3fd44072784b7094d6278500a35c44f35cfa82..99231e7253c3ce31f48baa0f8929ac9fdbcf156c 100644 (file)
@@ -1251,19 +1251,19 @@ fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T]
     }
 }
 
-#[experimental = "waiting on Deref stability"]
+#[stable]
 impl<T> ops::Deref for Vec<T> {
     type Target = [T];
 
     fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() }
 }
 
-#[experimental = "waiting on DerefMut stability"]
+#[stable]
 impl<T> ops::DerefMut for Vec<T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() }
 }
 
-#[experimental = "waiting on FromIterator stability"]
+#[stable]
 impl<T> FromIterator<T> for Vec<T> {
     #[inline]
     fn from_iter<I:Iterator<Item=T>>(mut iterator: I) -> Vec<T> {
@@ -1393,6 +1393,7 @@ fn as_slice<'a>(&'a self) -> &'a [T] {
     }
 }
 
+#[unstable = "recent addition, needs more experience"]
 impl<'a, T: Clone> Add<&'a [T]> for Vec<T> {
     type Output = Vec<T>;
 
@@ -1404,6 +1405,7 @@ fn add(mut self, rhs: &[T]) -> Vec<T> {
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<T> Drop for Vec<T> {
     fn drop(&mut self) {
         // This is (and should always remain) a no-op if the fields are
@@ -1449,6 +1451,7 @@ fn write_str(&mut self, s: &str) -> fmt::Result {
 /// A clone-on-write vector
 pub type CowVec<'a, T> = Cow<'a, Vec<T>, [T]>;
 
+#[unstable]
 impl<'a, T> FromIterator<T> for CowVec<'a, T> where T: Clone {
     fn from_iter<I: Iterator<Item=T>>(it: I) -> CowVec<'a, T> {
         Cow::Owned(FromIterator::from_iter(it))
@@ -1494,6 +1497,7 @@ pub fn into_inner(mut self) -> Vec<T> {
     }
 }
 
+#[stable]
 impl<T> Iterator for IntoIter<T> {
     type Item = T;
 
@@ -1530,6 +1534,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<T> DoubleEndedIterator for IntoIter<T> {
     #[inline]
     fn next_back<'a>(&'a mut self) -> Option<T> {
@@ -1553,9 +1558,11 @@ fn next_back<'a>(&'a mut self) -> Option<T> {
     }
 }
 
+#[stable]
 impl<T> ExactSizeIterator for IntoIter<T> {}
 
 #[unsafe_destructor]
+#[stable]
 impl<T> Drop for IntoIter<T> {
     fn drop(&mut self) {
         // destroy the remaining elements
@@ -1577,6 +1584,7 @@ pub struct Drain<'a, T> {
     marker: ContravariantLifetime<'a>,
 }
 
+#[stable]
 impl<'a, T> Iterator for Drain<'a, T> {
     type Item = T;
 
@@ -1613,6 +1621,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<'a, T> DoubleEndedIterator for Drain<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<T> {
@@ -1636,9 +1645,11 @@ fn next_back(&mut self) -> Option<T> {
     }
 }
 
+#[stable]
 impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
 
 #[unsafe_destructor]
+#[stable]
 impl<'a, T> Drop for Drain<'a, T> {
     fn drop(&mut self) {
         // self.ptr == self.end == null if drop has already been called,
@@ -1671,7 +1682,7 @@ fn deref<'b>(&'b self) -> &'b Vec<T> {
 
 // Prevent the inner `Vec<T>` from attempting to deallocate memory.
 #[unsafe_destructor]
-#[experimental]
+#[stable]
 impl<'a, T> Drop for DerefVec<'a, T> {
     fn drop(&mut self) {
         self.x.len = 0;
index 0ac0dc396cc1a304c566ca8fe41bb56c3696649c..15c20253c8bc78b1c739b28c14215e9484886455 100644 (file)
@@ -86,7 +86,7 @@ pub struct AtomicBool {
 unsafe impl Sync for AtomicBool {}
 
 /// A signed integer type which can be safely shared between threads.
-#[stable]
+#[unstable = "awaiting int/uint conventions, may be renamed"]
 pub struct AtomicInt {
     v: UnsafeCell<int>,
 }
@@ -94,7 +94,7 @@ pub struct AtomicInt {
 unsafe impl Sync for AtomicInt {}
 
 /// An unsigned integer type which can be safely shared between threads.
-#[stable]
+#[unstable = "awaiting int/uint conventions, may be renamed"]
 pub struct AtomicUint {
     v: UnsafeCell<uint>,
 }
@@ -146,28 +146,18 @@ pub enum Ordering {
 }
 
 /// An `AtomicBool` initialized to `false`.
-#[unstable = "may be renamed, pending conventions for static initalizers"]
+#[stable]
 pub const ATOMIC_BOOL_INIT: AtomicBool =
         AtomicBool { v: UnsafeCell { value: 0 } };
 /// An `AtomicInt` initialized to `0`.
-#[unstable = "may be renamed, pending conventions for static initalizers"]
+#[unstable = "awaiting int/uint conventions, may be renamed"]
 pub const ATOMIC_INT_INIT: AtomicInt =
         AtomicInt { v: UnsafeCell { value: 0 } };
 /// An `AtomicUint` initialized to `0`.
-#[unstable = "may be renamed, pending conventions for static initalizers"]
+#[unstable = "awaiting int/uint conventions, may be renamed"]
 pub const ATOMIC_UINT_INIT: AtomicUint =
         AtomicUint { v: UnsafeCell { value: 0, } };
 
-/// Deprecated
-#[deprecated = "renamed to ATOMIC_BOOL_INIT"]
-pub const INIT_ATOMIC_BOOL: AtomicBool = ATOMIC_BOOL_INIT;
-/// Deprecated
-#[deprecated = "renamed to ATOMIC_INT_INIT"]
-pub const INIT_ATOMIC_INT: AtomicInt = ATOMIC_INT_INIT;
-/// Deprecated
-#[deprecated = "renamed to ATOMIC_UINT_INIT"]
-pub const INIT_ATOMIC_UINT: AtomicUint = ATOMIC_UINT_INIT;
-
 // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
 const UINT_TRUE: uint = -1;
 
@@ -413,6 +403,7 @@ pub fn fetch_xor(&self, val: bool, order: Ordering) -> bool {
     }
 }
 
+#[unstable = "awaiting int/uint conventions, types may change"]
 impl AtomicInt {
     /// Creates a new `AtomicInt`.
     ///
@@ -424,7 +415,6 @@ impl AtomicInt {
     /// let atomic_forty_two  = AtomicInt::new(42);
     /// ```
     #[inline]
-    #[stable]
     pub fn new(v: int) -> AtomicInt {
         AtomicInt {v: UnsafeCell::new(v)}
     }
@@ -447,7 +437,6 @@ pub fn new(v: int) -> AtomicInt {
     /// let value = some_int.load(Ordering::Relaxed);
     /// ```
     #[inline]
-    #[stable]
     pub fn load(&self, order: Ordering) -> int {
         unsafe { atomic_load(self.v.get() as *const int, order) }
     }
@@ -470,7 +459,6 @@ pub fn load(&self, order: Ordering) -> int {
     ///
     /// Panics if `order` is `Acquire` or `AcqRel`.
     #[inline]
-    #[stable]
     pub fn store(&self, val: int, order: Ordering) {
         unsafe { atomic_store(self.v.get(), val, order); }
     }
@@ -489,7 +477,6 @@ pub fn store(&self, val: int, order: Ordering) {
     /// let value = some_int.swap(10, Ordering::Relaxed);
     /// ```
     #[inline]
-    #[stable]
     pub fn swap(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_swap(self.v.get(), val, order) }
     }
@@ -511,7 +498,6 @@ pub fn swap(&self, val: int, order: Ordering) -> int {
     /// let value = some_int.compare_and_swap(5, 10, Ordering::Relaxed);
     /// ```
     #[inline]
-    #[stable]
     pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int {
         unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
     }
@@ -528,7 +514,6 @@ pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int {
     /// assert_eq!(10, foo.load(Ordering::SeqCst));
     /// ```
     #[inline]
-    #[stable]
     pub fn fetch_add(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_add(self.v.get(), val, order) }
     }
@@ -545,7 +530,6 @@ pub fn fetch_add(&self, val: int, order: Ordering) -> int {
     /// assert_eq!(-10, foo.load(Ordering::SeqCst));
     /// ```
     #[inline]
-    #[stable]
     pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_sub(self.v.get(), val, order) }
     }
@@ -561,7 +545,6 @@ pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
     /// assert_eq!(0b101101, foo.fetch_and(0b110011, Ordering::SeqCst));
     /// assert_eq!(0b100001, foo.load(Ordering::SeqCst));
     #[inline]
-    #[stable]
     pub fn fetch_and(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_and(self.v.get(), val, order) }
     }
@@ -577,7 +560,6 @@ pub fn fetch_and(&self, val: int, order: Ordering) -> int {
     /// assert_eq!(0b101101, foo.fetch_or(0b110011, Ordering::SeqCst));
     /// assert_eq!(0b111111, foo.load(Ordering::SeqCst));
     #[inline]
-    #[stable]
     pub fn fetch_or(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_or(self.v.get(), val, order) }
     }
@@ -593,12 +575,12 @@ pub fn fetch_or(&self, val: int, order: Ordering) -> int {
     /// assert_eq!(0b101101, foo.fetch_xor(0b110011, Ordering::SeqCst));
     /// assert_eq!(0b011110, foo.load(Ordering::SeqCst));
     #[inline]
-    #[stable]
     pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
         unsafe { atomic_xor(self.v.get(), val, order) }
     }
 }
 
+#[unstable = "awaiting int/uint conventions, types may change"]
 impl AtomicUint {
     /// Creates a new `AtomicUint`.
     ///
@@ -610,7 +592,6 @@ impl AtomicUint {
     /// let atomic_forty_two = AtomicUint::new(42u);
     /// ```
     #[inline]
-    #[stable]
     pub fn new(v: uint) -> AtomicUint {
         AtomicUint { v: UnsafeCell::new(v) }
     }
@@ -633,7 +614,6 @@ pub fn new(v: uint) -> AtomicUint {
     /// let value = some_uint.load(Ordering::Relaxed);
     /// ```
     #[inline]
-    #[stable]
     pub fn load(&self, order: Ordering) -> uint {
         unsafe { atomic_load(self.v.get() as *const uint, order) }
     }
@@ -656,7 +636,6 @@ pub fn load(&self, order: Ordering) -> uint {
     ///
     /// Panics if `order` is `Acquire` or `AcqRel`.
     #[inline]
-    #[stable]
     pub fn store(&self, val: uint, order: Ordering) {
         unsafe { atomic_store(self.v.get(), val, order); }
     }
@@ -675,7 +654,6 @@ pub fn store(&self, val: uint, order: Ordering) {
     /// let value = some_uint.swap(10, Ordering::Relaxed);
     /// ```
     #[inline]
-    #[stable]
     pub fn swap(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_swap(self.v.get(), val, order) }
     }
@@ -697,7 +675,6 @@ pub fn swap(&self, val: uint, order: Ordering) -> uint {
     /// let value = some_uint.compare_and_swap(5, 10, Ordering::Relaxed);
     /// ```
     #[inline]
-    #[stable]
     pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint {
         unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
     }
@@ -714,7 +691,6 @@ pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint {
     /// assert_eq!(10, foo.load(Ordering::SeqCst));
     /// ```
     #[inline]
-    #[stable]
     pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_add(self.v.get(), val, order) }
     }
@@ -731,7 +707,6 @@ pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
     /// assert_eq!(0, foo.load(Ordering::SeqCst));
     /// ```
     #[inline]
-    #[stable]
     pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_sub(self.v.get(), val, order) }
     }
@@ -747,7 +722,6 @@ pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
     /// assert_eq!(0b101101, foo.fetch_and(0b110011, Ordering::SeqCst));
     /// assert_eq!(0b100001, foo.load(Ordering::SeqCst));
     #[inline]
-    #[stable]
     pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_and(self.v.get(), val, order) }
     }
@@ -763,7 +737,6 @@ pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
     /// assert_eq!(0b101101, foo.fetch_or(0b110011, Ordering::SeqCst));
     /// assert_eq!(0b111111, foo.load(Ordering::SeqCst));
     #[inline]
-    #[stable]
     pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_or(self.v.get(), val, order) }
     }
@@ -779,7 +752,6 @@ pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
     /// assert_eq!(0b101101, foo.fetch_xor(0b110011, Ordering::SeqCst));
     /// assert_eq!(0b011110, foo.load(Ordering::SeqCst));
     #[inline]
-    #[stable]
     pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
         unsafe { atomic_xor(self.v.get(), val, order) }
     }
index 7e4d73d598d8d8227bed2325082170b019a34f15..2c08b97635580c0504df846247a117644a491602 100644 (file)
 use self::Cow::*;
 
 /// A trait for borrowing data.
-pub trait BorrowFrom<Sized? Owned> for Sized? {
+#[old_orphan_check]
+pub trait BorrowFrom<Owned: ?Sized> {
     /// Immutably borrow from an owned value.
     fn borrow_from(owned: &Owned) -> &Self;
 }
 
 /// A trait for mutably borrowing data.
-pub trait BorrowFromMut<Sized? Owned> for Sized? : BorrowFrom<Owned> {
+#[old_orphan_check]
+pub trait BorrowFromMut<Owned: ?Sized> : BorrowFrom<Owned> {
     /// Mutably borrow from an owned value.
     fn borrow_from_mut(owned: &mut Owned) -> &mut Self;
 }
 
-impl<Sized? T> BorrowFrom<T> for T {
+impl<T: ?Sized> BorrowFrom<T> for T {
     fn borrow_from(owned: &T) -> &T { owned }
 }
 
-impl<Sized? T> BorrowFromMut<T> for T {
+impl<T: ?Sized> BorrowFromMut<T> for T {
     fn borrow_from_mut(owned: &mut T) -> &mut T { owned }
 }
 
-impl<'a, Sized? T> BorrowFrom<&'a T> for T {
+impl<'a, T: ?Sized> BorrowFrom<&'a T> for T {
     fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned }
 }
 
-impl<'a, Sized? T> BorrowFrom<&'a mut T> for T {
+impl<'a, T: ?Sized> BorrowFrom<&'a mut T> for T {
     fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned }
 }
 
-impl<'a, Sized? T> BorrowFromMut<&'a mut T> for T {
+impl<'a, T: ?Sized> BorrowFromMut<&'a mut T> for T {
     fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned }
 }
 
-impl<'a, T, Sized? B> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> {
+impl<'a, T, B: ?Sized> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> {
     fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B {
         &**owned
     }
 }
 
 /// Trait for moving into a `Cow`
-pub trait IntoCow<'a, T, Sized? B> {
+#[old_orphan_check]
+pub trait IntoCow<'a, T, B: ?Sized> {
     /// Moves `self` into `Cow`
     fn into_cow(self) -> Cow<'a, T, B>;
 }
 
-impl<'a, T, Sized? B> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> {
+impl<'a, T, B: ?Sized> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> {
     fn into_cow(self) -> Cow<'a, T, B> {
         self
     }
 }
 
 /// A generalization of Clone to borrowed data.
-pub trait ToOwned<Owned> for Sized?: BorrowFrom<Owned> {
+#[old_orphan_check]
+pub trait ToOwned<Owned>: BorrowFrom<Owned> {
     /// Create owned data from borrowed data, usually by copying.
     fn to_owned(&self) -> Owned;
 }
@@ -129,7 +133,7 @@ fn to_owned(&self) -> T { self.clone() }
 ///     }
 /// }
 /// ```
-pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned<T> {
+pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned<T> {
     /// Borrowed data.
     Borrowed(&'a B),
 
@@ -138,7 +142,7 @@ pub enum Cow<'a, T, Sized? B: 'a> where B: ToOwned<T> {
 }
 
 #[stable]
-impl<'a, T, Sized? B> Clone for Cow<'a, T, B> where B: ToOwned<T> {
+impl<'a, T, B: ?Sized> Clone for Cow<'a, T, B> where B: ToOwned<T> {
     fn clone(&self) -> Cow<'a, T, B> {
         match *self {
             Borrowed(b) => Borrowed(b),
@@ -150,7 +154,7 @@ fn clone(&self) -> Cow<'a, T, B> {
     }
 }
 
-impl<'a, T, Sized? B> Cow<'a, T, B> where B: ToOwned<T> {
+impl<'a, T, B: ?Sized> Cow<'a, T, B> where B: ToOwned<T> {
     /// Acquire a mutable reference to the owned form of the data.
     ///
     /// Copies the data if it is not already owned.
@@ -191,7 +195,8 @@ pub fn is_owned(&self) -> bool {
     }
 }
 
-impl<'a, T, Sized? B> Deref for Cow<'a, T, B> where B: ToOwned<T>  {
+#[stable]
+impl<'a, T, B: ?Sized> Deref for Cow<'a, T, B> where B: ToOwned<T>  {
     type Target = B;
 
     fn deref(&self) -> &B {
@@ -203,10 +208,10 @@ fn deref(&self) -> &B {
 }
 
 #[stable]
-impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}
+impl<'a, T, B: ?Sized> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}
 
 #[stable]
-impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
+impl<'a, T, B: ?Sized> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
     #[inline]
     fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
         Ord::cmp(&**self, &**other)
@@ -214,7 +219,7 @@ fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
 }
 
 #[stable]
-impl<'a, 'b, T, U, Sized? B, Sized? C> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
+impl<'a, 'b, T, U, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
     B: PartialEq<C> + ToOwned<T>,
     C: ToOwned<U>,
 {
@@ -225,14 +230,14 @@ fn eq(&self, other: &Cow<'b, U, C>) -> bool {
 }
 
 #[stable]
-impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
+impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
     #[inline]
     fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
         PartialOrd::partial_cmp(&**self, &**other)
     }
 }
 
-impl<'a, T, Sized? B> fmt::Show for Cow<'a, T, B> where B: fmt::Show + ToOwned<T>, T: fmt::Show {
+impl<'a, T, B: ?Sized> fmt::Show for Cow<'a, T, B> where B: fmt::Show + ToOwned<T>, T: fmt::Show {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             Borrowed(ref b) => fmt::Show::fmt(b, f),
index eb772388dce220834d000638830ab1986f8a27d5..fd18d6ac3f3b409e389b599e5292343feccb720f 100644 (file)
@@ -419,7 +419,7 @@ pub struct Ref<'b, T:'b> {
     _borrow: BorrowRef<'b>,
 }
 
-#[unstable = "waiting for `Deref` to become stable"]
+#[stable]
 impl<'b, T> Deref for Ref<'b, T> {
     type Target = T;
 
@@ -477,7 +477,7 @@ pub struct RefMut<'b, T:'b> {
     _borrow: BorrowRefMut<'b>,
 }
 
-#[unstable = "waiting for `Deref` to become stable"]
+#[stable]
 impl<'b, T> Deref for RefMut<'b, T> {
     type Target = T;
 
@@ -487,7 +487,7 @@ fn deref<'a>(&'a self) -> &'a T {
     }
 }
 
-#[unstable = "waiting for `DerefMut` to become stable"]
+#[stable]
 impl<'b, T> DerefMut for RefMut<'b, T> {
     #[inline]
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
index 291b7f2ece4455db05cd8777785240795501f5d2..caac894c0daa327c5ccf98edb285de9014b7fa08 100644 (file)
@@ -314,6 +314,7 @@ pub struct EscapeUnicode {
 }
 
 #[derive(Clone)]
+#[unstable]
 enum EscapeUnicodeState {
     Backslash,
     Type,
@@ -375,6 +376,7 @@ pub struct EscapeDefault {
 }
 
 #[derive(Clone)]
+#[unstable]
 enum EscapeDefaultState {
     Backslash(char),
     Char(char),
index 159c2a505d51b89c1b06b062b4b7d6ab70e41872..17991659f97899c6027021eae8a8dceecccd54a6 100644 (file)
@@ -43,7 +43,7 @@ fn clone_from(&mut self, source: &Self) {
 }
 
 #[stable]
-impl<'a, Sized? T> Clone for &'a T {
+impl<'a, T: ?Sized> Clone for &'a T {
     /// Return a shallow copy of the reference.
     #[inline]
     fn clone(&self) -> &'a T { *self }
index 13f9f5ccee9161b180ca4904abeb2af2c92b02bf..af5e98ed303240a9684c8207d9f4375eb208ccac 100644 (file)
@@ -69,7 +69,8 @@
 /// only if `a != b`.
 #[lang="eq"]
 #[stable]
-pub trait PartialEq<Sized? Rhs = Self> for Sized? {
+#[old_orphan_check]
+pub trait PartialEq<Rhs: ?Sized = Self> {
     /// This method tests for `self` and `other` values to be equal, and is used by `==`.
     #[stable]
     fn eq(&self, other: &Rhs) -> bool;
@@ -90,7 +91,7 @@ fn ne(&self, other: &Rhs) -> bool { !self.eq(other) }
 /// - symmetric: `a == b` implies `b == a`; and
 /// - transitive: `a == b` and `b == c` implies `a == c`.
 #[stable]
-pub trait Eq for Sized?: PartialEq<Self> {
+pub trait Eq: PartialEq<Self> {
     // FIXME #13101: this method is used solely by #[deriving] to
     // assert that every component of a type implements #[deriving]
     // itself, the current deriving infrastructure means doing this
@@ -164,7 +165,7 @@ pub fn reverse(self) -> Ordering {
 /// - transitive, `a < b` and `b < c` implies `a < c`. The same must hold for
 ///   both `==` and `>`.
 #[stable]
-pub trait Ord for Sized?: Eq + PartialOrd<Self> {
+pub trait Ord: Eq + PartialOrd<Self> {
     /// This method returns an ordering between `self` and `other` values.
     ///
     /// By convention, `self.cmp(&other)` returns the ordering matching
@@ -224,7 +225,7 @@ fn partial_cmp(&self, other: &Ordering) -> Option<Ordering> {
 /// 5.11).
 #[lang="ord"]
 #[stable]
-pub trait PartialOrd<Sized? Rhs = Self> for Sized?: PartialEq<Rhs> {
+pub trait PartialOrd<Rhs: ?Sized = Self>: PartialEq<Rhs> {
     /// This method returns an ordering between `self` and `other` values
     /// if one exists.
     #[stable]
@@ -428,14 +429,14 @@ fn cmp(&self, other: &bool) -> Ordering {
     // & pointers
 
     #[stable]
-    impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
+    impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a A where A: PartialEq<B> {
         #[inline]
         fn eq(&self, other: & &'b B) -> bool { PartialEq::eq(*self, *other) }
         #[inline]
         fn ne(&self, other: & &'b B) -> bool { PartialEq::ne(*self, *other) }
     }
     #[stable]
-    impl<'a, 'b, Sized? A, Sized? B> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> {
+    impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b B> for &'a A where A: PartialOrd<B> {
         #[inline]
         fn partial_cmp(&self, other: &&'b B) -> Option<Ordering> {
             PartialOrd::partial_cmp(*self, *other)
@@ -450,24 +451,24 @@ fn ge(&self, other: & &'b B) -> bool { PartialOrd::ge(*self, *other) }
         fn gt(&self, other: & &'b B) -> bool { PartialOrd::gt(*self, *other) }
     }
     #[stable]
-    impl<'a, Sized? A> Ord for &'a A where A: Ord {
+    impl<'a, A: ?Sized> Ord for &'a A where A: Ord {
         #[inline]
         fn cmp(&self, other: & &'a A) -> Ordering { Ord::cmp(*self, *other) }
     }
     #[stable]
-    impl<'a, Sized? A> Eq for &'a A where A: Eq {}
+    impl<'a, A: ?Sized> Eq for &'a A where A: Eq {}
 
     // &mut pointers
 
     #[stable]
-    impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
+    impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a mut A where A: PartialEq<B> {
         #[inline]
         fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
         #[inline]
         fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
     }
     #[stable]
-    impl<'a, 'b, Sized? A, Sized? B> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> {
+    impl<'a, 'b, A: ?Sized, B: ?Sized> PartialOrd<&'b mut B> for &'a mut A where A: PartialOrd<B> {
         #[inline]
         fn partial_cmp(&self, other: &&'b mut B) -> Option<Ordering> {
             PartialOrd::partial_cmp(*self, *other)
@@ -482,15 +483,15 @@ fn ge(&self, other: &&'b mut B) -> bool { PartialOrd::ge(*self, *other) }
         fn gt(&self, other: &&'b mut B) -> bool { PartialOrd::gt(*self, *other) }
     }
     #[stable]
-    impl<'a, Sized? A> Ord for &'a mut A where A: Ord {
+    impl<'a, A: ?Sized> Ord for &'a mut A where A: Ord {
         #[inline]
         fn cmp(&self, other: &&'a mut A) -> Ordering { Ord::cmp(*self, *other) }
     }
     #[stable]
-    impl<'a, Sized? A> Eq for &'a mut A where A: Eq {}
+    impl<'a, A: ?Sized> Eq for &'a mut A where A: Eq {}
 
     #[stable]
-    impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
+    impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b mut B> for &'a A where A: PartialEq<B> {
         #[inline]
         fn eq(&self, other: &&'b mut B) -> bool { PartialEq::eq(*self, *other) }
         #[inline]
@@ -498,7 +499,7 @@ fn ne(&self, other: &&'b mut B) -> bool { PartialEq::ne(*self, *other) }
     }
 
     #[stable]
-    impl<'a, 'b, Sized? A, Sized? B> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
+    impl<'a, 'b, A: ?Sized, B: ?Sized> PartialEq<&'b B> for &'a mut A where A: PartialEq<B> {
         #[inline]
         fn eq(&self, other: &&'b B) -> bool { PartialEq::eq(*self, *other) }
         #[inline]
index 102836f8d3024831044766fe17c0ec2062f66af3..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;
@@ -78,9 +81,9 @@ fn write_fmt(&mut self, args: Arguments) -> Result {
         // This Adapter is needed to allow `self` (of type `&mut
         // Self`) to be cast to a FormatWriter (below) without
         // requiring a `Sized` bound.
-        struct Adapter<'a,Sized? T:'a>(&'a mut T);
+        struct Adapter<'a,T: ?Sized +'a>(&'a mut T);
 
-        impl<'a, Sized? T> Writer for Adapter<'a, T>
+        impl<'a, T: ?Sized> Writer for Adapter<'a, T>
             where T: Writer
         {
             fn write_str(&mut self, s: &str) -> Result {
@@ -222,7 +225,7 @@ fn fmt(&self, fmt: &mut Formatter) -> Result {
 /// to this trait. There is not an explicit way of selecting this trait to be
 /// used for formatting, it is only if no other format is specified.
 #[unstable = "I/O and core have yet to be reconciled"]
-pub trait Show for Sized? {
+pub trait Show {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
 }
@@ -230,49 +233,49 @@ pub trait Show for Sized? {
 
 /// Format trait for the `o` character
 #[unstable = "I/O and core have yet to be reconciled"]
-pub trait Octal for Sized? {
+pub trait Octal {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `b` character
 #[unstable = "I/O and core have yet to be reconciled"]
-pub trait Binary for Sized? {
+pub trait Binary {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `x` character
 #[unstable = "I/O and core have yet to be reconciled"]
-pub trait LowerHex for Sized? {
+pub trait LowerHex {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `X` character
 #[unstable = "I/O and core have yet to be reconciled"]
-pub trait UpperHex for Sized? {
+pub trait UpperHex {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `p` character
 #[unstable = "I/O and core have yet to be reconciled"]
-pub trait Pointer for Sized? {
+pub trait Pointer {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `e` character
 #[unstable = "I/O and core have yet to be reconciled"]
-pub trait LowerExp for Sized? {
+pub trait LowerExp {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
 }
 
 /// Format trait for the `E` character
 #[unstable = "I/O and core have yet to be reconciled"]
-pub trait UpperExp for Sized? {
+pub trait UpperExp {
     /// Formats the value using the given formatter.
     fn fmt(&self, &mut Formatter) -> Result;
 }
@@ -592,10 +595,10 @@ pub fn argumentuint<'a>(s: &'a uint) -> Argument<'a> {
 
 // Implementations of the core formatting traits
 
-impl<'a, Sized? T: Show> Show for &'a T {
+impl<'a, T: ?Sized + Show> Show for &'a T {
     fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
 }
-impl<'a, Sized? T: Show> Show for &'a mut T {
+impl<'a, T: ?Sized + Show> Show for &'a mut T {
     fn fmt(&self, f: &mut Formatter) -> Result { (**self).fmt(f) }
 }
 
index b0a5ec9fe12ed5caf7650cf5ac4eb0c1034d90b6..d8b9cf9594d6aab4cfb7ed4eedf15a06ef00aa08 100644 (file)
@@ -76,7 +76,7 @@
 /// A hashable type. The `S` type parameter is an abstract hash state that is
 /// used by the `Hash` to compute the hash. It defaults to
 /// `std::hash::sip::SipState`.
-pub trait Hash<S = sip::SipState> for Sized? {
+pub trait Hash<S = sip::SipState> {
     /// Computes the hash of a value.
     fn hash(&self, state: &mut S);
 }
@@ -85,7 +85,7 @@ pub trait Hash<S = sip::SipState> for Sized? {
 /// containers like `HashMap`, which need a generic way hash multiple types.
 pub trait Hasher<S> {
     /// Compute the hash of a value.
-    fn hash<Sized? T: Hash<S>>(&self, value: &T) -> u64;
+    fn hash<T: ?Sized + Hash<S>>(&self, value: &T) -> u64;
 }
 
 #[allow(missing_docs)]
@@ -194,14 +194,14 @@ fn hash(&self, state: &mut S) {
 }
 
 
-impl<'a, S: Writer, Sized? T: Hash<S>> Hash<S> for &'a T {
+impl<'a, S: Writer, T: ?Sized + Hash<S>> Hash<S> for &'a T {
     #[inline]
     fn hash(&self, state: &mut S) {
         (**self).hash(state);
     }
 }
 
-impl<'a, S: Writer, Sized? T: Hash<S>> Hash<S> for &'a mut T {
+impl<'a, S: Writer, T: ?Sized + Hash<S>> Hash<S> for &'a mut T {
     #[inline]
     fn hash(&self, state: &mut S) {
         (**self).hash(state);
@@ -233,7 +233,7 @@ fn hash(&self, state: &mut S) {
     }
 }
 
-impl<'a, T, Sized? B, S> Hash<S> for Cow<'a, T, B> where B: Hash<S> + ToOwned<T> {
+impl<'a, T, B: ?Sized, S> Hash<S> for Cow<'a, T, B> where B: Hash<S> + ToOwned<T> {
     #[inline]
     fn hash(&self, state: &mut S) {
         Hash::hash(&**self, state)
index f9da0493f3edb0761629e65a3d32169aecae7b44..c4d45e9c2c80454802496457b1f8e3b17dc3762f 100644 (file)
@@ -239,7 +239,7 @@ pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
 
 impl Hasher<SipState> for SipHasher {
     #[inline]
-    fn hash<Sized? T: Hash<SipState>>(&self, value: &T) -> u64 {
+    fn hash<T: ?Sized + Hash<SipState>>(&self, value: &T) -> u64 {
         let mut state = SipState::new_with_keys(self.k0, self.k1);
         value.hash(&mut state);
         state.result()
@@ -255,7 +255,7 @@ fn default() -> SipHasher {
 
 /// Hashes a value using the SipHash algorithm.
 #[inline]
-pub fn hash<Sized? T: Hash<SipState>>(value: &T) -> u64 {
+pub fn hash<T: ?Sized + Hash<SipState>>(value: &T) -> u64 {
     let mut state = SipState::new();
     value.hash(&mut state);
     state.result()
@@ -263,7 +263,7 @@ pub fn hash<Sized? T: Hash<SipState>>(value: &T) -> u64 {
 
 /// Hashes a value with the SipHash algorithm with the provided keys.
 #[inline]
-pub fn hash_with_keys<Sized? T: Hash<SipState>>(k0: u64, k1: u64, value: &T) -> u64 {
+pub fn hash_with_keys<T: ?Sized + Hash<SipState>>(k0: u64, k1: u64, value: &T) -> u64 {
     let mut state = SipState::new_with_keys(k0, k1);
     value.hash(&mut state);
     state.result()
index 29077deb21de16a74c59819166414273c621e84b..e5753f6cc2e7857e6e76c3a7cc3d4eaa5e151b89 100644 (file)
@@ -54,6 +54,8 @@
 //!
 //! This `for` loop syntax can be applied to any iterator over any type.
 
+#![stable]
+
 use self::MinMaxResult::*;
 
 use clone::Clone;
 /// it wishes, either by returning `None` infinitely, or by doing something
 /// else.
 #[lang="iterator"]
-#[unstable = "just split up for object safety"]
+#[stable]
 pub trait Iterator {
+    #[stable]
     type Item;
 
     /// Advance the iterator and return the next value. Return `None` when the end is reached.
+    #[stable]
     fn next(&mut self) -> Option<Self::Item>;
 
     /// Returns a lower and upper bound on the remaining length of the iterator.
@@ -91,26 +95,80 @@ pub trait Iterator {
     /// An upper bound of `None` means either there is no known upper bound, or the upper bound
     /// does not fit within a `uint`.
     #[inline]
+    #[stable]
     fn size_hint(&self) -> (uint, Option<uint>) { (0, None) }
 }
 
 /// Conversion from an `Iterator`
-#[unstable = "may be replaced by a more general conversion trait"]
+#[stable]
 pub trait FromIterator<A> {
     /// Build a container with elements from an external iterator.
     fn from_iter<T: Iterator<Item=A>>(iterator: T) -> Self;
 }
 
 /// A type growable from an `Iterator` implementation
-#[unstable = "just renamed as part of collections reform"]
+#[stable]
 pub trait Extend<A> {
     /// Extend a container with the elements yielded by an arbitrary iterator
     fn extend<T: Iterator<Item=A>>(&mut self, iterator: T);
 }
 
-#[unstable = "new convention for extension traits"]
 /// An extension trait providing numerous methods applicable to all iterators.
+#[stable]
 pub trait IteratorExt: Iterator + Sized {
+    /// Counts the number of elements in this iterator.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let a = [1i, 2, 3, 4, 5];
+    /// let mut it = a.iter();
+    /// assert!(it.count() == 5);
+    /// ```
+    #[inline]
+    #[stable]
+    fn count(self) -> uint {
+        self.fold(0, |cnt, _x| cnt + 1)
+    }
+
+    /// Loops through the entire iterator, returning the last element of the
+    /// iterator.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let a = [1i, 2, 3, 4, 5];
+    /// assert!(a.iter().last().unwrap() == &5);
+    /// ```
+    #[inline]
+    #[stable]
+    fn last(mut self) -> Option< <Self as Iterator>::Item> {
+        let mut last = None;
+        for x in self { last = Some(x); }
+        last
+    }
+
+    /// Loops through `n` iterations, returning the `n`th element of the
+    /// iterator.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let a = [1i, 2, 3, 4, 5];
+    /// let mut it = a.iter();
+    /// assert!(it.nth(2).unwrap() == &3);
+    /// assert!(it.nth(2) == None);
+    /// ```
+    #[inline]
+    #[stable]
+    fn nth(&mut self, mut n: uint) -> Option< <Self as Iterator>::Item> {
+        for x in *self {
+            if n == 0 { return Some(x) }
+            n -= 1;
+        }
+        None
+    }
+
     /// Chain this iterator with another, returning a new iterator that will
     /// finish iterating over the current iterator, and then iterate
     /// over the other specified iterator.
@@ -169,7 +227,7 @@ fn zip<B, U>(self, other: U) -> Zip<Self, U> where
     /// assert!(it.next().is_none());
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn map<B, F>(self, f: F) -> Map< <Self as Iterator>::Item, B, Self, F> where
         F: FnMut(<Self as Iterator>::Item) -> B,
     {
@@ -189,7 +247,7 @@ fn map<B, F>(self, f: F) -> Map< <Self as Iterator>::Item, B, Self, F> where
     /// assert!(it.next().is_none());
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn filter<P>(self, predicate: P) -> Filter< <Self as Iterator>::Item, Self, P> where
         P: FnMut(&<Self as Iterator>::Item) -> bool,
     {
@@ -209,7 +267,7 @@ fn filter<P>(self, predicate: P) -> Filter< <Self as Iterator>::Item, Self, P> w
     /// assert!(it.next().is_none());
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn filter_map<B, F>(self, f: F) -> FilterMap< <Self as Iterator>::Item, B, Self, F> where
         F: FnMut(<Self as Iterator>::Item) -> Option<B>,
     {
@@ -258,9 +316,9 @@ fn peekable(self) -> Peekable< <Self as Iterator>::Item, Self> {
         Peekable{iter: self, peeked: None}
     }
 
-    /// Creates an iterator that invokes the predicate on elements until it
-    /// returns false. Once the predicate returns false, all further elements are
-    /// yielded.
+    /// Creates an iterator that invokes the predicate on elements
+    /// until it returns false. Once the predicate returns false, that
+    /// element and all further elements are yielded.
     ///
     /// # Example
     ///
@@ -273,7 +331,7 @@ fn peekable(self) -> Peekable< <Self as Iterator>::Item, Self> {
     /// assert!(it.next().is_none());
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn skip_while<P>(self, predicate: P) -> SkipWhile< <Self as Iterator>::Item, Self, P> where
         P: FnMut(&<Self as Iterator>::Item) -> bool,
     {
@@ -294,7 +352,7 @@ fn skip_while<P>(self, predicate: P) -> SkipWhile< <Self as Iterator>::Item, Sel
     /// assert!(it.next().is_none());
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures, may want to require peek"]
+    #[stable]
     fn take_while<P>(self, predicate: P) -> TakeWhile< <Self as Iterator>::Item, Self, P> where
         P: FnMut(&<Self as Iterator>::Item) -> bool,
     {
@@ -359,7 +417,7 @@ fn take(self, n: uint) -> Take<Self> {
     /// assert!(it.next().is_none());
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn scan<St, B, F>(
         self,
         initial_state: St,
@@ -389,7 +447,7 @@ fn scan<St, B, F>(
     /// }
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn flat_map<B, U, F>(self, f: F) -> FlatMap< <Self as Iterator>::Item, B, Self, U, F> where
         U: Iterator<Item=B>,
         F: FnMut(<Self as Iterator>::Item) -> U,
@@ -449,7 +507,7 @@ fn fuse(self) -> Fuse<Self> {
     /// println!("{}", sum);
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn inspect<F>(self, f: F) -> Inspect< <Self as Iterator>::Item, Self, F> where
         F: FnMut(&<Self as Iterator>::Item),
     {
@@ -487,7 +545,7 @@ fn by_ref<'r>(&'r mut self) -> ByRef<'r, Self> {
     /// assert!(a.as_slice() == b.as_slice());
     /// ```
     #[inline]
-    #[unstable = "waiting for general conversion traits, just changed to take self by value"]
+    #[stable]
     fn collect<B: FromIterator< <Self as Iterator>::Item>>(self) -> B {
         FromIterator::from_iter(self)
     }
@@ -522,44 +580,6 @@ fn partition<B, F>(mut self, mut f: F) -> (B, B) where
         (left, right)
     }
 
-    /// Loops through `n` iterations, returning the `n`th element of the
-    /// iterator.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let a = [1i, 2, 3, 4, 5];
-    /// let mut it = a.iter();
-    /// assert!(it.nth(2).unwrap() == &3);
-    /// assert!(it.nth(2) == None);
-    /// ```
-    #[inline]
-    #[stable]
-    fn nth(&mut self, mut n: uint) -> Option< <Self as Iterator>::Item> {
-        for x in *self {
-            if n == 0 { return Some(x) }
-            n -= 1;
-        }
-        None
-    }
-
-    /// Loops through the entire iterator, returning the last element of the
-    /// iterator.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let a = [1i, 2, 3, 4, 5];
-    /// assert!(a.iter().last().unwrap() == &5);
-    /// ```
-    #[inline]
-    #[unstable = "just changed to take self by value"]
-    fn last(mut self) -> Option< <Self as Iterator>::Item> {
-        let mut last = None;
-        for x in self { last = Some(x); }
-        last
-    }
-
     /// Performs a fold operation over the entire iterator, returning the
     /// eventual state at the end of the iteration.
     ///
@@ -570,7 +590,7 @@ fn last(mut self) -> Option< <Self as Iterator>::Item> {
     /// assert!(a.iter().fold(0, |a, &b| a + b) == 15);
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures, just changed to take self by value"]
+    #[stable]
     fn fold<B, F>(mut self, init: B, mut f: F) -> B where
         F: FnMut(B, <Self as Iterator>::Item) -> B,
     {
@@ -581,21 +601,6 @@ fn fold<B, F>(mut self, init: B, mut f: F) -> B where
         accum
     }
 
-    /// Counts the number of elements in this iterator.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let a = [1i, 2, 3, 4, 5];
-    /// let mut it = a.iter();
-    /// assert!(it.count() == 5);
-    /// ```
-    #[inline]
-    #[unstable = "just changed to take self by value"]
-    fn count(self) -> uint {
-        self.fold(0, |cnt, _x| cnt + 1)
-    }
-
     /// Tests whether the predicate holds true for all elements in the iterator.
     ///
     /// # Example
@@ -606,7 +611,7 @@ fn count(self) -> uint {
     /// assert!(!a.iter().all(|x| *x > 2));
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures, just changed to take self by value"]
+    #[stable]
     fn all<F>(mut self, mut f: F) -> bool where F: FnMut(<Self as Iterator>::Item) -> bool {
         for x in self { if !f(x) { return false; } }
         true
@@ -624,7 +629,7 @@ fn all<F>(mut self, mut f: F) -> bool where F: FnMut(<Self as Iterator>::Item) -
     /// assert!(!it.any(|x| *x == 3));
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn any<F>(&mut self, mut f: F) -> bool where F: FnMut(<Self as Iterator>::Item) -> bool {
         for x in *self { if f(x) { return true; } }
         false
@@ -634,7 +639,7 @@ fn any<F>(&mut self, mut f: F) -> bool where F: FnMut(<Self as Iterator>::Item)
     ///
     /// Does not consume the iterator past the first found element.
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn find<P>(&mut self, mut predicate: P) -> Option< <Self as Iterator>::Item> where
         P: FnMut(&<Self as Iterator>::Item) -> bool,
     {
@@ -646,7 +651,7 @@ fn find<P>(&mut self, mut predicate: P) -> Option< <Self as Iterator>::Item> whe
 
     /// Return the index of the first element satisfying the specified predicate
     #[inline]
-    #[unstable = "waiting for unboxed closures"]
+    #[stable]
     fn position<P>(&mut self, mut predicate: P) -> Option<uint> where
         P: FnMut(<Self as Iterator>::Item) -> bool,
     {
@@ -660,6 +665,145 @@ fn position<P>(&mut self, mut predicate: P) -> Option<uint> where
         None
     }
 
+    /// Return the index of the last element satisfying the specified predicate
+    ///
+    /// If no element matches, None is returned.
+    #[inline]
+    #[stable]
+    fn rposition<P>(&mut self, mut predicate: P) -> Option<uint> where
+        P: FnMut(<Self as Iterator>::Item) -> bool,
+        Self: ExactSizeIterator + DoubleEndedIterator
+    {
+        let len = self.len();
+        for i in range(0, len).rev() {
+            if predicate(self.next_back().expect("rposition: incorrect ExactSizeIterator")) {
+                return Some(i);
+            }
+        }
+        None
+    }
+
+    /// Consumes the entire iterator to return the maximum element.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let a = [1i, 2, 3, 4, 5];
+    /// assert!(a.iter().max().unwrap() == &5);
+    /// ```
+    #[inline]
+    #[stable]
+    fn max(self) -> Option< <Self as Iterator>::Item> where
+        <Self as Iterator>::Item: Ord
+    {
+        self.fold(None, |max, x| {
+            match max {
+                None    => Some(x),
+                Some(y) => Some(cmp::max(x, y))
+            }
+        })
+    }
+
+    /// Consumes the entire iterator to return the minimum element.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let a = [1i, 2, 3, 4, 5];
+    /// assert!(a.iter().min().unwrap() == &1);
+    /// ```
+    #[inline]
+    #[stable]
+    fn min(self) -> Option< <Self as Iterator>::Item> where
+        <Self as Iterator>::Item: Ord
+    {
+        self.fold(None, |min, x| {
+            match min {
+                None    => Some(x),
+                Some(y) => Some(cmp::min(x, y))
+            }
+        })
+    }
+
+    /// `min_max` finds the minimum and maximum elements in the iterator.
+    ///
+    /// The return type `MinMaxResult` is an enum of three variants:
+    ///
+    /// - `NoElements` if the iterator is empty.
+    /// - `OneElement(x)` if the iterator has exactly one element.
+    /// - `MinMax(x, y)` is returned otherwise, where `x <= y`. Two
+    ///    values are equal if and only if there is more than one
+    ///    element in the iterator and all elements are equal.
+    ///
+    /// On an iterator of length `n`, `min_max` does `1.5 * n` comparisons,
+    /// and so is faster than calling `min` and `max` separately which does `2 * n` comparisons.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
+    ///
+    /// let v: [int; 0] = [];
+    /// assert_eq!(v.iter().min_max(), NoElements);
+    ///
+    /// let v = [1i];
+    /// assert!(v.iter().min_max() == OneElement(&1));
+    ///
+    /// let v = [1i, 2, 3, 4, 5];
+    /// assert!(v.iter().min_max() == MinMax(&1, &5));
+    ///
+    /// let v = [1i, 2, 3, 4, 5, 6];
+    /// assert!(v.iter().min_max() == MinMax(&1, &6));
+    ///
+    /// let v = [1i, 1, 1, 1];
+    /// assert!(v.iter().min_max() == MinMax(&1, &1));
+    /// ```
+    #[unstable = "return type may change"]
+    fn min_max(mut self) -> MinMaxResult< <Self as Iterator>::Item> where
+        <Self as Iterator>::Item: Ord
+    {
+        let (mut min, mut max) = match self.next() {
+            None => return NoElements,
+            Some(x) => {
+                match self.next() {
+                    None => return OneElement(x),
+                    Some(y) => if x < y {(x, y)} else {(y,x)}
+                }
+            }
+        };
+
+        loop {
+            // `first` and `second` are the two next elements we want to look at.
+            // We first compare `first` and `second` (#1). The smaller one is then compared to
+            // current minimum (#2). The larger one is compared to current maximum (#3). This
+            // way we do 3 comparisons for 2 elements.
+            let first = match self.next() {
+                None => break,
+                Some(x) => x
+            };
+            let second = match self.next() {
+                None => {
+                    if first < min {
+                        min = first;
+                    } else if first > max {
+                        max = first;
+                    }
+                    break;
+                }
+                Some(x) => x
+            };
+            if first < second {
+                if first < min {min = first;}
+                if max < second {max = second;}
+            } else {
+                if second < min {min = second;}
+                if max < first {max = first;}
+            }
+        }
+
+        MinMax(min, max)
+    }
+
     /// Return the element that gives the maximum value from the
     /// specified function.
     ///
@@ -672,7 +816,7 @@ fn position<P>(&mut self, mut predicate: P) -> Option<uint> where
     /// assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures, just changed to take self by value"]
+    #[unstable = "may want to produce an Ordering directly; see #15311"]
     fn max_by<B: Ord, F>(self, mut f: F) -> Option< <Self as Iterator>::Item> where
         F: FnMut(&<Self as Iterator>::Item) -> B,
     {
@@ -701,7 +845,7 @@ fn max_by<B: Ord, F>(self, mut f: F) -> Option< <Self as Iterator>::Item> where
     /// assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
     /// ```
     #[inline]
-    #[unstable = "waiting for unboxed closures, just changed to take self by value"]
+    #[unstable = "may want to produce an Ordering directly; see #15311"]
     fn min_by<B: Ord, F>(self, mut f: F) -> Option< <Self as Iterator>::Item> where
         F: FnMut(&<Self as Iterator>::Item) -> B,
     {
@@ -740,6 +884,7 @@ fn rev(self) -> Rev<Self> {
     ///
     /// Loops through the entire iterator, collecting the first component of
     /// each item into one new container, and the second component into another.
+    #[unstable = "recent addition"]
     fn unzip<A, B, FromA, FromB>(mut self) -> (FromA, FromB) where
         FromA: Default + Extend<A>,
         FromB: Default + Extend<B>,
@@ -759,56 +904,73 @@ fn size_hint(&self) -> (uint, Option<uint>) {
         let mut ts: FromA = Default::default();
         let mut us: FromB = Default::default();
 
-        ts.extend(SizeHint(lo, hi));
-        us.extend(SizeHint(lo, hi));
+        ts.extend(SizeHint(lo, hi));
+        us.extend(SizeHint(lo, hi));
+
+        for (t, u) in self {
+            ts.extend(Some(t).into_iter());
+            us.extend(Some(u).into_iter());
+        }
+
+        (ts, us)
+    }
+
+    /// Creates an iterator that clones the elements it yields. Useful for converting an
+    /// Iterator<&T> to an Iterator<T>.
+    #[unstable = "recent addition"]
+    fn cloned<T, D>(self) -> Cloned<Self> where
+        Self: Iterator<Item=D>,
+        D: Deref<Target=T>,
+        T: Clone,
+    {
+        Cloned { it: self }
+    }
+
+    /// Repeats an iterator endlessly
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::iter::count;
+    ///
+    /// let a = count(1i,1i).take(1);
+    /// let mut cy = a.cycle();
+    /// assert_eq!(cy.next(), Some(1));
+    /// assert_eq!(cy.next(), Some(1));
+    /// ```
+    #[stable]
+    #[inline]
+    fn cycle(self) -> Cycle<Self> where Self: Clone {
+        Cycle{orig: self.clone(), iter: self}
+    }
 
-        for (t, u) in self {
-            ts.extend(Some(t).into_iter());
-            us.extend(Some(u).into_iter());
+    /// Use an iterator to reverse a container in place.
+    #[experimental = "uncertain about placement or widespread use"]
+    fn reverse_in_place<'a, T: 'a>(&mut self) where
+        Self: Iterator<Item=&'a mut T> + DoubleEndedIterator
+    {
+        loop {
+            match (self.next(), self.next_back()) {
+                (Some(x), Some(y)) => mem::swap(x, y),
+                _ => break
+            }
         }
-
-        (ts, us)
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> IteratorExt for I where I: Iterator {}
 
 /// A range iterator able to yield elements from both ends
 ///
 /// A `DoubleEndedIterator` can be thought of as a deque in that `next()` and `next_back()` exhaust
 /// elements from the *same* range, and do not work independently of each other.
-#[unstable = "recently split into two traits"]
+#[stable]
 pub trait DoubleEndedIterator: Iterator {
     /// Yield an element from the end of the range, returning `None` if the range is empty.
     fn next_back(&mut self) -> Option< <Self as Iterator>::Item>;
 }
 
-/// A double-ended iterator yielding mutable references
-#[experimental = "not widely used"]
-pub trait MutableDoubleEndedIterator {
-    // FIXME: #5898: should be called `reverse`
-    /// Use an iterator to reverse a container in-place
-    fn reverse_(&mut self);
-}
-
-#[experimental = "trait is experimental"]
-impl<'a, T:'a, I> MutableDoubleEndedIterator for I where
-    I: DoubleEndedIterator + Iterator<Item=&'a mut T>,
-{
-    // FIXME: #5898: should be called `reverse`
-    /// Use an iterator to reverse a container in-place
-    fn reverse_(&mut self) {
-        loop {
-            match (self.next(), self.next_back()) {
-                (Some(x), Some(y)) => mem::swap(x, y),
-                _ => break
-            }
-        }
-    }
-}
-
-
 /// An object implementing random access indexing by `uint`
 ///
 /// A `RandomAccessIterator` should be either infinite or a `DoubleEndedIterator`.
@@ -832,24 +994,8 @@ pub trait RandomAccessIterator: Iterator {
 ///
 /// `Iterator::size_hint` *must* return the exact size of the iterator.
 /// Note that the size must fit in `uint`.
-#[unstable = "could move DoubleEndedIterator bound onto rposition with method-level where clauses"]
-pub trait ExactSizeIterator: DoubleEndedIterator {
-    /// Return the index of the last element satisfying the specified predicate
-    ///
-    /// If no element matches, None is returned.
-    #[inline]
-    fn rposition<P>(&mut self, mut predicate: P) -> Option<uint> where
-        P: FnMut(<Self as Iterator>::Item) -> bool,
-    {
-        let len = self.len();
-        for i in range(0, len).rev() {
-            if predicate(self.next_back().expect("rposition: incorrect ExactSizeIterator")) {
-                return Some(i);
-            }
-        }
-        None
-    }
-
+#[stable]
+pub trait ExactSizeIterator: Iterator {
     #[inline]
     /// Return the exact length of the iterator.
     fn len(&self) -> uint {
@@ -865,21 +1011,21 @@ fn len(&self) -> uint {
 
 // All adaptors that preserve the size of the wrapped iterator are fine
 // Adaptors that may overflow in `size_hint` are not, i.e. `Chain`.
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> ExactSizeIterator for Enumerate<I> where I: ExactSizeIterator {}
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, I, F> ExactSizeIterator for Inspect<A, I, F> where
     I: ExactSizeIterator + Iterator<Item=A>,
     F: FnMut(&A),
 {}
-#[unstable = "trait is unstable"]
-impl<I> ExactSizeIterator for Rev<I> where I: ExactSizeIterator {}
-#[unstable = "trait is unstable"]
+#[stable]
+impl<I> ExactSizeIterator for Rev<I> where I: ExactSizeIterator + DoubleEndedIterator {}
+#[stable]
 impl<A, B, I, F> ExactSizeIterator for Map<A, B, I, F> where
     I: ExactSizeIterator + Iterator<Item=A>,
     F: FnMut(A) -> B,
 {}
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, B> ExactSizeIterator for Zip<A, B> where A: ExactSizeIterator, B: ExactSizeIterator {}
 
 /// An double-ended iterator with the direction inverted
@@ -890,7 +1036,7 @@ pub struct Rev<T> {
     iter: T
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
     type Item = <I as Iterator>::Item;
 
@@ -900,7 +1046,7 @@ fn next(&mut self) -> Option< <I as Iterator>::Item> { self.iter.next_back() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> DoubleEndedIterator for Rev<I> where I: DoubleEndedIterator {
     #[inline]
     fn next_back(&mut self) -> Option< <I as Iterator>::Item> { self.iter.next() }
@@ -924,7 +1070,7 @@ pub struct ByRef<'a, I:'a> {
     iter: &'a mut I,
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<'a, I> Iterator for ByRef<'a, I> where I: 'a + Iterator {
     type Item = <I as Iterator>::Item;
 
@@ -934,7 +1080,7 @@ fn next(&mut self) -> Option< <I as Iterator>::Item> { self.iter.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.iter.size_hint() }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<'a, I> DoubleEndedIterator for ByRef<'a, I> where I: 'a + DoubleEndedIterator {
     #[inline]
     fn next_back(&mut self) -> Option< <I as Iterator>::Item> { self.iter.next_back() }
@@ -1025,134 +1171,9 @@ fn product(self) -> $A {
 impl_multiplicative! { f32,  1.0 }
 impl_multiplicative! { f64,  1.0 }
 
-/// A trait for iterators over elements which can be compared to one another.
-#[unstable = "recently renamed for new extension trait conventions"]
-pub trait IteratorOrdExt<A> {
-    /// Consumes the entire iterator to return the maximum element.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let a = [1i, 2, 3, 4, 5];
-    /// assert!(a.iter().max().unwrap() == &5);
-    /// ```
-    fn max(self) -> Option<A>;
-
-    /// Consumes the entire iterator to return the minimum element.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let a = [1i, 2, 3, 4, 5];
-    /// assert!(a.iter().min().unwrap() == &1);
-    /// ```
-    fn min(self) -> Option<A>;
-
-    /// `min_max` finds the minimum and maximum elements in the iterator.
-    ///
-    /// The return type `MinMaxResult` is an enum of three variants:
-    ///
-    /// - `NoElements` if the iterator is empty.
-    /// - `OneElement(x)` if the iterator has exactly one element.
-    /// - `MinMax(x, y)` is returned otherwise, where `x <= y`. Two
-    ///    values are equal if and only if there is more than one
-    ///    element in the iterator and all elements are equal.
-    ///
-    /// On an iterator of length `n`, `min_max` does `1.5 * n` comparisons,
-    /// and so is faster than calling `min` and `max` separately which does `2 * n` comparisons.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
-    ///
-    /// let v: [int; 0] = [];
-    /// assert_eq!(v.iter().min_max(), NoElements);
-    ///
-    /// let v = [1i];
-    /// assert!(v.iter().min_max() == OneElement(&1));
-    ///
-    /// let v = [1i, 2, 3, 4, 5];
-    /// assert!(v.iter().min_max() == MinMax(&1, &5));
-    ///
-    /// let v = [1i, 2, 3, 4, 5, 6];
-    /// assert!(v.iter().min_max() == MinMax(&1, &6));
-    ///
-    /// let v = [1i, 1, 1, 1];
-    /// assert!(v.iter().min_max() == MinMax(&1, &1));
-    /// ```
-    fn min_max(self) -> MinMaxResult<A>;
-}
-
-#[unstable = "trait is unstable"]
-impl<T, I> IteratorOrdExt<T> for I where I: Iterator<Item=T>, T: Ord {
-    #[inline]
-    fn max(self) -> Option<T> {
-        self.fold(None, |max, x| {
-            match max {
-                None    => Some(x),
-                Some(y) => Some(cmp::max(x, y))
-            }
-        })
-    }
-
-    #[inline]
-    fn min(self) -> Option<T> {
-        self.fold(None, |min, x| {
-            match min {
-                None    => Some(x),
-                Some(y) => Some(cmp::min(x, y))
-            }
-        })
-    }
-
-    fn min_max(mut self) -> MinMaxResult<T> {
-        let (mut min, mut max) = match self.next() {
-            None => return NoElements,
-            Some(x) => {
-                match self.next() {
-                    None => return OneElement(x),
-                    Some(y) => if x < y {(x, y)} else {(y,x)}
-                }
-            }
-        };
-
-        loop {
-            // `first` and `second` are the two next elements we want to look at.
-            // We first compare `first` and `second` (#1). The smaller one is then compared to
-            // current minimum (#2). The larger one is compared to current maximum (#3). This
-            // way we do 3 comparisons for 2 elements.
-            let first = match self.next() {
-                None => break,
-                Some(x) => x
-            };
-            let second = match self.next() {
-                None => {
-                    if first < min {
-                        min = first;
-                    } else if first > max {
-                        max = first;
-                    }
-                    break;
-                }
-                Some(x) => x
-            };
-            if first < second {
-                if first < min {min = first;}
-                if max < second {max = second;}
-            } else {
-                if second < min {min = second;}
-                if max < first {max = first;}
-            }
-        }
-
-        MinMax(min, max)
-    }
-}
-
 /// `MinMaxResult` is an enum returned by `min_max`. See `IteratorOrdExt::min_max` for more detail.
 #[derive(Clone, PartialEq, Show)]
-#[unstable = "waiting on namespaced enum conventions"]
+#[unstable = "unclear whether such a fine-grained result is widely useful"]
 pub enum MinMaxResult<T> {
     /// Empty iterator
     NoElements,
@@ -1164,7 +1185,6 @@ pub enum MinMaxResult<T> {
     MinMax(T, T)
 }
 
-#[stable]
 impl<T: Clone> MinMaxResult<T> {
     /// `into_option` creates an `Option` of type `(T,T)`. The returned `Option` has variant
     /// `None` if and only if the `MinMaxResult` has variant `NoElements`. Otherwise variant
@@ -1185,6 +1205,7 @@ impl<T: Clone> MinMaxResult<T> {
     /// let r = MinMax(1i,2i);
     /// assert_eq!(r.into_option(), Some((1,2)));
     /// ```
+    #[unstable = "type is unstable"]
     pub fn into_option(self) -> Option<(T,T)> {
         match self {
             NoElements => None,
@@ -1194,30 +1215,15 @@ pub fn into_option(self) -> Option<(T,T)> {
     }
 }
 
-/// A trait for iterators that contain cloneable elements
-#[unstable = "recently renamed for extension trait conventions"]
-pub trait IteratorCloneExt<A> {
-    /// Creates an iterator that clones the elements it yields. Useful for converting an
-    /// Iterator<&T> to an Iterator<T>.
-    fn cloned(self) -> Cloned<Self>;
-}
-
-#[unstable = "trait is unstable"]
-impl<T, D, I> IteratorCloneExt<T> for I where
-    T: Clone,
-    D: Deref<Target=T>,
-    I: Iterator<Item=D>,
-{
-    fn cloned(self) -> Cloned<I> {
-        Cloned { it: self }
-    }
-}
-
 /// An iterator that clones the elements of an underlying iterator
+#[unstable = "recent addition"]
+#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
+#[derive(Clone)]
 pub struct Cloned<I> {
     it: I,
 }
 
+#[stable]
 impl<T, D, I> Iterator for Cloned<I> where
     T: Clone,
     D: Deref<Target=T>,
@@ -1234,6 +1240,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<T, D, I> DoubleEndedIterator for Cloned<I> where
     T: Clone,
     D: Deref<Target=T>,
@@ -1244,39 +1251,13 @@ fn next_back(&mut self) -> Option<T> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<T, D, I> ExactSizeIterator for Cloned<I> where
     T: Clone,
     D: Deref<Target=T>,
     I: ExactSizeIterator + Iterator<Item=D>,
 {}
 
-#[unstable = "recently renamed for extension trait conventions"]
-/// An extension trait for cloneable iterators.
-pub trait CloneIteratorExt {
-    /// Repeats an iterator endlessly
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use std::iter::{CloneIteratorExt, count};
-    ///
-    /// let a = count(1i,1i).take(1);
-    /// let mut cy = a.cycle();
-    /// assert_eq!(cy.next(), Some(1));
-    /// assert_eq!(cy.next(), Some(1));
-    /// ```
-    #[stable]
-    fn cycle(self) -> Cycle<Self>;
-}
-
-impl<I> CloneIteratorExt for I where I: Iterator + Clone {
-    #[inline]
-    fn cycle(self) -> Cycle<I> {
-        Cycle{orig: self.clone(), iter: self}
-    }
-}
-
 /// An iterator that repeats endlessly
 #[derive(Clone, Copy)]
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
@@ -1286,6 +1267,7 @@ pub struct Cycle<I> {
     iter: I,
 }
 
+#[stable]
 impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
     type Item = <I as Iterator>::Item;
 
@@ -1345,7 +1327,7 @@ pub struct Chain<A, B> {
     flag: bool,
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<T, A, B> Iterator for Chain<A, B> where A: Iterator<Item=T>, B: Iterator<Item=T> {
     type Item = T;
 
@@ -1379,7 +1361,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<T, A, B> DoubleEndedIterator for Chain<A, B> where
     A: DoubleEndedIterator + Iterator<Item=T>,
     B: DoubleEndedIterator + Iterator<Item=T>,
@@ -1424,7 +1406,7 @@ pub struct Zip<A, B> {
     b: B
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<T, U, A, B> Iterator for Zip<A, B> where
     A: Iterator<Item = T>,
     B: Iterator<Item = U>,
@@ -1460,10 +1442,10 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<T, U, A, B> DoubleEndedIterator for Zip<A, B> where
-    A: ExactSizeIterator + Iterator<Item=T>,
-    B: ExactSizeIterator + Iterator<Item=U>,
+    A: ExactSizeIterator + Iterator<Item=T> + DoubleEndedIterator,
+    B: ExactSizeIterator + Iterator<Item=U> + DoubleEndedIterator,
 {
     #[inline]
     fn next_back(&mut self) -> Option<(T, U)> {
@@ -1539,7 +1521,7 @@ fn do_map(&mut self, elt: Option<A>) -> Option<B> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, B, I, F> Iterator for Map<A, B, I, F> where I: Iterator<Item=A>, F: FnMut(A) -> B {
     type Item = B;
 
@@ -1555,7 +1537,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, B, I, F> DoubleEndedIterator for Map<A, B, I, F> where
     I: DoubleEndedIterator + Iterator<Item=A>,
     F: FnMut(A) -> B,
@@ -1606,7 +1588,7 @@ fn clone(&self) -> Filter<A, I, P> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, I, P> Iterator for Filter<A, I, P> where I: Iterator<Item=A>, P: FnMut(&A) -> bool {
     type Item = A;
 
@@ -1629,7 +1611,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, I, P> DoubleEndedIterator for Filter<A, I, P> where
     I: DoubleEndedIterator + Iterator<Item=A>,
     P: FnMut(&A) -> bool,
@@ -1667,7 +1649,7 @@ fn clone(&self) -> FilterMap<A, B, I, F> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, B, I, F> Iterator for FilterMap<A, B, I, F> where
     I: Iterator<Item=A>,
     F: FnMut(A) -> Option<B>,
@@ -1692,7 +1674,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, B, I, F> DoubleEndedIterator for FilterMap<A, B, I, F> where
     I: DoubleEndedIterator + Iterator<Item=A>,
     F: FnMut(A) -> Option<B>,
@@ -1718,7 +1700,7 @@ pub struct Enumerate<I> {
     count: uint
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> Iterator for Enumerate<I> where I: Iterator {
     type Item = (uint, <I as Iterator>::Item);
 
@@ -1740,8 +1722,10 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
-impl<I> DoubleEndedIterator for Enumerate<I> where I: ExactSizeIterator {
+#[stable]
+impl<I> DoubleEndedIterator for Enumerate<I> where
+    I: ExactSizeIterator + DoubleEndedIterator
+{
     #[inline]
     fn next_back(&mut self) -> Option<(uint, <I as Iterator>::Item)> {
         match self.iter.next_back() {
@@ -1779,6 +1763,7 @@ pub struct Peekable<T, I> where I: Iterator<Item=T> {
     peeked: Option<T>,
 }
 
+#[stable]
 impl<T, I> Iterator for Peekable<T, I> where I: Iterator<Item=T> {
     type Item = T;
 
@@ -1850,7 +1835,7 @@ fn clone(&self) -> SkipWhile<A, I, P> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, I, P> Iterator for SkipWhile<A, I, P> where I: Iterator<Item=A>, P: FnMut(&A) -> bool {
     type Item = A;
 
@@ -1896,7 +1881,7 @@ fn clone(&self) -> TakeWhile<A, I, P> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, I, P> Iterator for TakeWhile<A, I, P> where I: Iterator<Item=A>, P: FnMut(&A) -> bool {
     type Item = A;
 
@@ -1935,7 +1920,7 @@ pub struct Skip<I> {
     n: uint
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> Iterator for Skip<I> where I: Iterator {
     type Item = <I as Iterator>::Item;
 
@@ -2005,7 +1990,7 @@ pub struct Take<I> {
     n: uint
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> Iterator for Take<I> where I: Iterator{
     type Item = <I as Iterator>::Item;
 
@@ -2054,7 +2039,7 @@ fn idx(&mut self, index: uint) -> Option< <I as Iterator>::Item> {
 
 /// An iterator to maintain state while iterating another iterator
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
-#[unstable = "waiting for unboxed closures"]
+#[stable]
 pub struct Scan<A, B, I, St, F> where I: Iterator, F: FnMut(&mut St, A) -> Option<B> {
     iter: I,
     f: F,
@@ -2079,7 +2064,7 @@ fn clone(&self) -> Scan<A, B, I, St, F> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, B, I, St, F> Iterator for Scan<A, B, I, St, F> where
     I: Iterator<Item=A>,
     F: FnMut(&mut St, A) -> Option<B>,
@@ -2102,7 +2087,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 /// and yields the elements of the produced iterators
 ///
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
-#[unstable = "waiting for unboxed closures"]
+#[stable]
 pub struct FlatMap<A, B, I, U, F> where
     I: Iterator<Item=A>,
     U: Iterator<Item=B>,
@@ -2131,7 +2116,7 @@ fn clone(&self) -> FlatMap<A, B, I, U, F> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, B, I, U, F> Iterator for FlatMap<A, B, I, U, F> where
     I: Iterator<Item=A>,
     U: Iterator<Item=B>,
@@ -2166,7 +2151,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, B, I, U, F> DoubleEndedIterator for FlatMap<A, B, I, U, F> where
     I: DoubleEndedIterator + Iterator<Item=A>,
     U: DoubleEndedIterator + Iterator<Item=B>,
@@ -2199,7 +2184,7 @@ pub struct Fuse<I> {
     done: bool
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> Iterator for Fuse<I> where I: Iterator {
     type Item = <I as Iterator>::Item;
 
@@ -2228,7 +2213,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<I> DoubleEndedIterator for Fuse<I> where I: DoubleEndedIterator {
     #[inline]
     fn next_back(&mut self) -> Option< <I as Iterator>::Item> {
@@ -2260,11 +2245,11 @@ fn idx(&mut self, index: uint) -> Option< <I as Iterator>::Item> {
     }
 }
 
-#[experimental = "seems marginal"]
 impl<I> Fuse<I> {
     /// Resets the fuse such that the next call to .next() or .next_back() will
     /// call the underlying iterator again even if it previously returned None.
     #[inline]
+    #[experimental = "seems marginal"]
     pub fn reset_fuse(&mut self) {
         self.done = false
     }
@@ -2273,7 +2258,7 @@ pub fn reset_fuse(&mut self) {
 /// An iterator that calls a function with a reference to each
 /// element before yielding it.
 #[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
-#[unstable = "waiting for unboxed closures"]
+#[stable]
 pub struct Inspect<A, I, F> where I: Iterator<Item=A>, F: FnMut(&A) {
     iter: I,
     f: F,
@@ -2305,7 +2290,7 @@ fn do_inspect(&mut self, elt: Option<A>) -> Option<A> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, I, F> Iterator for Inspect<A, I, F> where I: Iterator<Item=A>, F: FnMut(&A) {
     type Item = A;
 
@@ -2321,7 +2306,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A, I, F> DoubleEndedIterator for Inspect<A, I, F> where
     I: DoubleEndedIterator + Iterator<Item=A>,
     F: FnMut(&A),
@@ -2416,7 +2401,7 @@ pub fn new(initial_state: St, f: F) -> Unfold<A, St, F> {
     }
 }
 
-#[experimental]
+#[stable]
 impl<A, St, F> Iterator for Unfold<A, St, F> where F: FnMut(&mut St) -> Option<A> {
     type Item = A;
 
@@ -2435,7 +2420,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 /// An infinite iterator starting at `start` and advancing by `step` with each
 /// iteration
 #[derive(Clone, Copy)]
-#[unstable = "may be renamed"]
+#[unstable = "may be renamed or replaced by range notation adapaters"]
 pub struct Counter<A> {
     /// The current state the counter is at (next value to be yielded)
     state: A,
@@ -2445,12 +2430,12 @@ pub struct Counter<A> {
 
 /// Creates a new counter with the specified start/step
 #[inline]
-#[unstable = "may be renamed"]
+#[unstable = "may be renamed or replaced by range notation adapaters"]
 pub fn count<A>(start: A, step: A) -> Counter<A> {
     Counter{state: start, step: step}
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A: Add<Output=A> + Clone> Iterator for Counter<A> {
     type Item = A;
 
@@ -2469,7 +2454,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 
 /// An iterator over the range [start, stop)
 #[derive(Clone, Copy)]
-#[unstable = "may be refactored due to numerics reform or ops reform"]
+#[unstable = "will be replaced by range notation"]
 pub struct Range<A> {
     state: A,
     stop: A,
@@ -2490,6 +2475,7 @@ pub struct Range<A> {
 /// }
 /// ```
 #[inline]
+#[unstable = "will be replaced by range notation"]
 pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
     Range {
         state: start,
@@ -2499,7 +2485,7 @@ pub fn range<A: Int>(start: A, stop: A) -> Range<A> {
 }
 
 // FIXME: #10414: Unfortunate type bound
-#[unstable = "trait is unstable"]
+#[unstable = "will be replaced by range notation"]
 impl<A: Int + ToPrimitive> Iterator for Range<A> {
     type Item = A;
 
@@ -2549,7 +2535,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 
 /// `Int` is required to ensure the range will be the same regardless of
 /// the direction it is consumed.
-#[unstable = "trait is unstable"]
+#[unstable = "will be replaced by range notation"]
 impl<A: Int + ToPrimitive> DoubleEndedIterator for Range<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
@@ -2564,7 +2550,7 @@ fn next_back(&mut self) -> Option<A> {
 
 /// An iterator over the range [start, stop]
 #[derive(Clone)]
-#[unstable = "may be refactored due to numerics reform or ops reform"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 pub struct RangeInclusive<A> {
     range: Range<A>,
     done: bool,
@@ -2572,7 +2558,7 @@ pub struct RangeInclusive<A> {
 
 /// Return an iterator over the range [start, stop]
 #[inline]
-#[unstable = "may be refactored due to numerics reform or ops reform"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
     RangeInclusive {
         range: range(start, stop),
@@ -2580,7 +2566,7 @@ pub fn range_inclusive<A: Int>(start: A, stop: A) -> RangeInclusive<A> {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 impl<A: Int + ToPrimitive> Iterator for RangeInclusive<A> {
     type Item = A;
 
@@ -2615,7 +2601,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[unstable = "trait is unstable"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 impl<A: Int + ToPrimitive> DoubleEndedIterator for RangeInclusive<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> {
@@ -2634,7 +2620,7 @@ fn next_back(&mut self) -> Option<A> {
 
 /// An iterator over the range [start, stop) by `step`. It handles overflow by stopping.
 #[derive(Clone)]
-#[unstable = "may be refactored due to numerics reform or ops reform"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 pub struct RangeStep<A> {
     state: A,
     stop: A,
@@ -2644,13 +2630,13 @@ pub struct RangeStep<A> {
 
 /// Return an iterator over the range [start, stop) by `step`. It handles overflow by stopping.
 #[inline]
-#[unstable = "may be refactored due to numerics reform or ops reform"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 pub fn range_step<A: Int>(start: A, stop: A, step: A) -> RangeStep<A> {
     let rev = step < Int::zero();
     RangeStep{state: start, stop: stop, step: step, rev: rev}
 }
 
-#[unstable = "trait is unstable"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 impl<A: Int> Iterator for RangeStep<A> {
     type Item = A;
 
@@ -2671,7 +2657,7 @@ fn next(&mut self) -> Option<A> {
 
 /// An iterator over the range [start, stop] by `step`. It handles overflow by stopping.
 #[derive(Clone)]
-#[unstable = "may be refactored due to numerics reform or ops reform"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 pub struct RangeStepInclusive<A> {
     state: A,
     stop: A,
@@ -2682,7 +2668,7 @@ pub struct RangeStepInclusive<A> {
 
 /// Return an iterator over the range [start, stop] by `step`. It handles overflow by stopping.
 #[inline]
-#[unstable = "may be refactored due to numerics reform or ops reform"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepInclusive<A> {
     let rev = step < Int::zero();
     RangeStepInclusive {
@@ -2694,7 +2680,7 @@ pub fn range_step_inclusive<A: Int>(start: A, stop: A, step: A) -> RangeStepIncl
     }
 }
 
-#[unstable = "trait is unstable"]
+#[unstable = "likely to be replaced by range notation and adapters"]
 impl<A: Int> Iterator for RangeStepInclusive<A> {
     type Item = A;
 
@@ -2719,7 +2705,7 @@ fn next(&mut self) -> Option<A> {
 /// directions. The `steps_between` function provides a way to
 /// compare two Step objects (it could be provided using `step()` and `Ord`,
 /// but the implementation would be so inefficient as to be useless).
-#[unstable = "Trait is unstable."]
+#[unstable = "design of range notation/iteration is in flux"]
 pub trait Step: Ord {
     /// Change self to the next object.
     fn step(&mut self);
@@ -2779,7 +2765,7 @@ pub struct Repeat<A> {
     element: A
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A: Clone> Iterator for Repeat<A> {
     type Item = A;
 
@@ -2789,7 +2775,7 @@ fn next(&mut self) -> Option<A> { self.idx(0) }
     fn size_hint(&self) -> (uint, Option<uint>) { (uint::MAX, None) }
 }
 
-#[unstable = "trait is unstable"]
+#[stable]
 impl<A: Clone> DoubleEndedIterator for Repeat<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> { self.idx(0) }
@@ -2855,7 +2841,7 @@ pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
 ///
 /// If two sequences are equal up until the point where one ends,
 /// the shorter sequence compares less.
-#[experimental = "likely to be removed after cmp reform"]
+#[unstable = "needs review and revision"]
 pub mod order {
     use cmp;
     use cmp::{Eq, Ord, PartialOrd, PartialEq};
index e50aaef5f09f3de77ebfb3d0a10a39a84fecddfc..5d69938fccff702adc1d8184f4503c3c899a26af 100644 (file)
 
 /// Types able to be transferred across task boundaries.
 #[lang="send"]
-pub unsafe trait Send for Sized? : 'static {
+pub unsafe trait Send : 'static {
     // empty.
 }
 
 /// Types with a constant size known at compile-time.
 #[lang="sized"]
-pub trait Sized for Sized? {
+pub trait Sized {
     // Empty.
 }
 
 /// Types that can be copied by simply copying bits (i.e. `memcpy`).
 #[lang="copy"]
-pub trait Copy for Sized? {
+pub trait Copy {
     // Empty.
 }
 
@@ -81,7 +81,7 @@ pub trait Copy for Sized? {
 /// reference; not doing this is undefined behaviour (for example,
 /// `transmute`-ing from `&T` to `&mut T` is illegal).
 #[lang="sync"]
-pub unsafe trait Sync for Sized? {
+pub unsafe trait Sync {
     // Empty
 }
 
@@ -133,10 +133,10 @@ pub mod marker {
     /// for some lifetime `'a`, but not the other way around).
     #[lang="covariant_type"]
     #[derive(PartialEq, Eq, PartialOrd, Ord)]
-    pub struct CovariantType<Sized? T>;
+    pub struct CovariantType<T: ?Sized>;
 
-    impl<Sized? T> Copy for CovariantType<T> {}
-    impl<Sized? T> Clone for CovariantType<T> {
+    impl<T: ?Sized> Copy for CovariantType<T> {}
+    impl<T: ?Sized> Clone for CovariantType<T> {
         fn clone(&self) -> CovariantType<T> { *self }
     }
 
@@ -181,10 +181,10 @@ fn clone(&self) -> CovariantType<T> { *self }
     /// arguments of type `U`, hence such a conversion is safe.
     #[lang="contravariant_type"]
     #[derive(PartialEq, Eq, PartialOrd, Ord)]
-    pub struct ContravariantType<Sized? T>;
+    pub struct ContravariantType<T: ?Sized>;
 
-    impl<Sized? T> Copy for ContravariantType<T> {}
-    impl<Sized? T> Clone for ContravariantType<T> {
+    impl<T: ?Sized> Copy for ContravariantType<T> {}
+    impl<T: ?Sized> Clone for ContravariantType<T> {
         fn clone(&self) -> ContravariantType<T> { *self }
     }
 
@@ -211,10 +211,10 @@ fn clone(&self) -> ContravariantType<T> { *self }
     /// interior mutability.
     #[lang="invariant_type"]
     #[derive(PartialEq, Eq, PartialOrd, Ord)]
-    pub struct InvariantType<Sized? T>;
+    pub struct InvariantType<T: ?Sized>;
 
-    impl<Sized? T> Copy for InvariantType<T> {}
-    impl<Sized? T> Clone for InvariantType<T> {
+    impl<T: ?Sized> Copy for InvariantType<T> {}
+    impl<T: ?Sized> Clone for InvariantType<T> {
         fn clone(&self) -> InvariantType<T> { *self }
     }
 
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 2620928acc1acca5070786ac304568f20dbb194d..c60569161213f68949bed4524688bc4978982d93 100644 (file)
@@ -320,7 +320,7 @@ pub unsafe fn transmute_copy<T, U>(src: &T) -> U {
 #[inline]
 #[unstable = "this function may be removed in the future due to its \
               questionable utility"]
-pub unsafe fn copy_lifetime<'a, Sized? S, Sized? T: 'a>(_ptr: &'a S,
+pub unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                         ptr: &T) -> &'a T {
     transmute(ptr)
 }
@@ -329,7 +329,7 @@ pub unsafe fn copy_lifetime<'a, Sized? S, Sized? T: 'a>(_ptr: &'a S,
 #[inline]
 #[unstable = "this function may be removed in the future due to its \
               questionable utility"]
-pub unsafe fn copy_mut_lifetime<'a, Sized? S, Sized? T: 'a>(_ptr: &'a mut S,
+pub unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a mut S,
                                                             ptr: &mut T)
                                                             -> &'a mut T {
     transmute(ptr)
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 17e4c5f8215a8a2314b61aceedc738a6e950ecdb..97d94e73bb33a0625764ba677ebdf97e49f8fe6f 100644 (file)
@@ -59,6 +59,8 @@
 //! See the documentation for each trait for a minimum implementation that prints
 //! something to the screen.
 
+#![stable]
+
 use clone::Clone;
 use iter::{Step, Iterator,DoubleEndedIterator,ExactSizeIterator};
 use kinds::Sized;
 /// }
 /// ```
 #[lang="drop"]
+#[stable]
 pub trait Drop {
     /// The `drop` method, called when the value goes out of scope.
+    #[stable]
     fn drop(&mut self);
 }
 
@@ -120,15 +124,19 @@ pub trait Drop {
 /// }
 /// ```
 #[lang="add"]
+#[stable]
 pub trait Add<RHS=Self> {
+    #[stable]
     type Output;
 
     /// The method for the `+` operator
+    #[stable]
     fn add(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! add_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl Add for $t {
             type Output = $t;
 
@@ -169,15 +177,19 @@ fn add(self, other: $t) -> $t { self + other }
 /// }
 /// ```
 #[lang="sub"]
+#[stable]
 pub trait Sub<RHS=Self> {
+    #[stable]
     type Output;
 
     /// The method for the `-` operator
+    #[stable]
     fn sub(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! sub_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl Sub for $t {
             type Output = $t;
 
@@ -218,15 +230,19 @@ fn sub(self, other: $t) -> $t { self - other }
 /// }
 /// ```
 #[lang="mul"]
+#[stable]
 pub trait Mul<RHS=Self> {
+    #[stable]
     type Output;
 
     /// The method for the `*` operator
+    #[stable]
     fn mul(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! mul_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl Mul for $t {
             type Output = $t;
 
@@ -267,15 +283,19 @@ fn mul(self, other: $t) -> $t { self * other }
 /// }
 /// ```
 #[lang="div"]
+#[stable]
 pub trait Div<RHS=Self> {
+    #[stable]
     type Output;
 
     /// The method for the `/` operator
+    #[stable]
     fn div(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! div_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl Div for $t {
             type Output = $t;
 
@@ -316,15 +336,19 @@ fn div(self, other: $t) -> $t { self / other }
 /// }
 /// ```
 #[lang="rem"]
+#[stable]
 pub trait Rem<RHS=Self> {
+    #[stable]
     type Output = Self;
 
     /// The method for the `%` operator
+    #[stable]
     fn rem(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! rem_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl Rem for $t {
             type Output = $t;
 
@@ -336,6 +360,7 @@ fn rem(self, other: $t) -> $t { self % other }
 
 macro_rules! rem_float_impl {
     ($t:ty, $fmod:ident) => {
+        #[stable]
         impl Rem for $t {
             type Output = $t;
 
@@ -382,19 +407,25 @@ fn rem(self, other: $t) -> $t {
 /// }
 /// ```
 #[lang="neg"]
+#[stable]
 pub trait Neg {
+    #[stable]
     type Output;
 
     /// The method for the unary `-` operator
+    #[stable]
     fn neg(self) -> Self::Output;
 }
 
 macro_rules! neg_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl Neg for $t {
+            #[stable]
             type Output = $t;
 
             #[inline]
+            #[stable]
             fn neg(self) -> $t { -self }
         }
     )*)
@@ -402,6 +433,7 @@ fn neg(self) -> $t { -self }
 
 macro_rules! neg_uint_impl {
     ($t:ty, $t_signed:ty) => {
+        #[stable]
         impl Neg for $t {
             type Output = $t;
 
@@ -450,15 +482,19 @@ fn neg(self) -> $t { -(self as $t_signed) as $t }
 /// }
 /// ```
 #[lang="not"]
+#[stable]
 pub trait Not {
+    #[stable]
     type Output;
 
     /// The method for the unary `!` operator
+    #[stable]
     fn not(self) -> Self::Output;
 }
 
 macro_rules! not_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl Not for $t {
             type Output = $t;
 
@@ -499,15 +535,19 @@ fn not(self) -> $t { !self }
 /// }
 /// ```
 #[lang="bitand"]
+#[stable]
 pub trait BitAnd<RHS=Self> {
+    #[stable]
     type Output;
 
     /// The method for the `&` operator
+    #[stable]
     fn bitand(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! bitand_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl BitAnd for $t {
             type Output = $t;
 
@@ -548,15 +588,19 @@ fn bitand(self, rhs: $t) -> $t { self & rhs }
 /// }
 /// ```
 #[lang="bitor"]
+#[stable]
 pub trait BitOr<RHS=Self> {
+    #[stable]
     type Output;
 
     /// The method for the `|` operator
+    #[stable]
     fn bitor(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! bitor_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl BitOr for $t {
             type Output = $t;
 
@@ -597,15 +641,19 @@ fn bitor(self, rhs: $t) -> $t { self | rhs }
 /// }
 /// ```
 #[lang="bitxor"]
+#[stable]
 pub trait BitXor<RHS=Self> {
+    #[stable]
     type Output;
 
     /// The method for the `^` operator
+    #[stable]
     fn bitxor(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! bitxor_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl BitXor for $t {
             type Output = $t;
 
@@ -646,15 +694,19 @@ fn bitxor(self, other: $t) -> $t { self ^ other }
 /// }
 /// ```
 #[lang="shl"]
+#[stable]
 pub trait Shl<RHS> {
+    #[stable]
     type Output;
 
     /// The method for the `<<` operator
+    #[stable]
     fn shl(self, rhs: RHS) -> Self::Output;
 }
 
 macro_rules! shl_impl {
     ($($t:ty)*) => ($(
+        #[stable]
         impl Shl<uint> for $t {
             type Output = $t;
 
@@ -697,10 +749,13 @@ fn shl(self, other: uint) -> $t {
 /// }
 /// ```
 #[lang="shr"]
+#[stable]
 pub trait Shr<RHS> {
+    #[stable]
     type Output;
 
     /// The method for the `>>` operator
+    #[stable]
     fn shr(self, rhs: RHS) -> Self::Output;
 }
 
@@ -747,8 +802,8 @@ fn shr(self, other: uint) -> $t { self >> other }
 /// }
 /// ```
 #[lang="index"]
-pub trait Index<Sized? Index> for Sized? {
-    type Sized? Output;
+pub trait Index<Index: ?Sized> {
+    type Output: ?Sized;
 
     /// The method for the indexing (`Foo[Bar]`) operation
     fn index<'a>(&'a self, index: &Index) -> &'a Self::Output;
@@ -784,8 +839,8 @@ pub trait Index<Sized? Index> for Sized? {
 /// }
 /// ```
 #[lang="index_mut"]
-pub trait IndexMut<Sized? Index> for Sized? {
-    type Sized? Output;
+pub trait IndexMut<Index: ?Sized> {
+    type Output: ?Sized;
 
     /// The method for the indexing (`Foo[Bar]`) operation
     fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Self::Output;
@@ -829,7 +884,7 @@ pub trait IndexMut<Sized? Index> for Sized? {
 /// }
 /// ```
 #[lang="slice"]
-pub trait Slice<Sized? Idx, Sized? Result> for Sized? {
+pub trait Slice<Idx: ?Sized, Result: ?Sized> {
     /// The method for the slicing operation foo[]
     fn as_slice_<'a>(&'a self) -> &'a Result;
     /// The method for the slicing operation foo[from..]
@@ -878,7 +933,7 @@ pub trait Slice<Sized? Idx, Sized? Result> for Sized? {
 /// }
 /// ```
 #[lang="slice_mut"]
-pub trait SliceMut<Sized? Idx, Sized? Result> for Sized? {
+pub trait SliceMut<Idx: ?Sized, Result: ?Sized> {
     /// The method for the slicing operation foo[]
     fn as_mut_slice_<'a>(&'a mut self) -> &'a mut Result;
     /// The method for the slicing operation foo[from..]
@@ -893,11 +948,13 @@ pub trait SliceMut<Sized? Idx, Sized? Result> for Sized? {
 /// An unbounded range.
 #[derive(Copy)]
 #[lang="full_range"]
+#[unstable = "API still in development"]
 pub struct FullRange;
 
 /// A (half-open) range which is bounded at both ends.
 #[derive(Copy)]
 #[lang="range"]
+#[unstable = "API still in development"]
 pub struct Range<Idx> {
     /// The lower bound of the range (inclusive).
     pub start: Idx,
@@ -907,6 +964,7 @@ pub struct Range<Idx> {
 
 // FIXME(#19391) needs a snapshot
 //impl<Idx: Clone + Step<T=uint>> Iterator<Idx> for Range<Idx> {
+#[unstable = "API still in development"]
 impl<Idx: Clone + Step> Iterator for Range<Idx> {
     type Item = Idx;
 
@@ -931,6 +989,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[unstable = "API still in development"]
 impl<Idx: Clone + Step> DoubleEndedIterator for Range<Idx> {
     #[inline]
     fn next_back(&mut self) -> Option<Idx> {
@@ -943,16 +1002,19 @@ fn next_back(&mut self) -> Option<Idx> {
     }
 }
 
+#[unstable = "API still in development"]
 impl<Idx: Clone + Step> ExactSizeIterator for Range<Idx> {}
 
 /// A range which is only bounded below.
 #[derive(Copy)]
 #[lang="range_from"]
+#[unstable = "API still in development"]
 pub struct RangeFrom<Idx> {
     /// The lower bound of the range (inclusive).
     pub start: Idx,
 }
 
+#[unstable = "API still in development"]
 impl<Idx: Clone + Step> Iterator for RangeFrom<Idx> {
     type Item = Idx;
 
@@ -968,6 +1030,7 @@ fn next(&mut self) -> Option<Idx> {
 /// A range which is only bounded above.
 #[derive(Copy)]
 #[lang="range_to"]
+#[unstable = "API still in development"]
 pub struct RangeTo<Idx> {
     /// The upper bound of the range (exclusive).
     pub end: Idx,
@@ -1005,20 +1068,25 @@ pub struct RangeTo<Idx> {
 /// }
 /// ```
 #[lang="deref"]
-pub trait Deref for Sized? {
-    type Sized? Target;
+#[stable]
+pub trait Deref {
+    #[stable]
+    type Target: ?Sized;
 
     /// The method called to dereference a value
+    #[stable]
     fn deref<'a>(&'a self) -> &'a Self::Target;
 }
 
-impl<'a, Sized? T> Deref for &'a T {
+#[stable]
+impl<'a, T: ?Sized> Deref for &'a T {
     type Target = T;
 
     fn deref(&self) -> &T { *self }
 }
 
-impl<'a, Sized? T> Deref for &'a mut T {
+#[stable]
+impl<'a, T: ?Sized> Deref for &'a mut T {
     type Target = T;
 
     fn deref(&self) -> &T { *self }
@@ -1062,38 +1130,44 @@ fn deref(&self) -> &T { *self }
 /// }
 /// ```
 #[lang="deref_mut"]
-pub trait DerefMut for Sized? : Deref {
+#[stable]
+pub trait DerefMut: Deref {
     /// The method called to mutably dereference a value
+    #[stable]
     fn deref_mut<'a>(&'a mut self) -> &'a mut <Self as Deref>::Target;
 }
 
-impl<'a, Sized? T> DerefMut for &'a mut T {
+#[stable]
+impl<'a, T: ?Sized> DerefMut for &'a mut T {
     fn deref_mut(&mut self) -> &mut T { *self }
 }
 
 /// A version of the call operator that takes an immutable receiver.
 #[lang="fn"]
-pub trait Fn<Args,Result> for Sized? {
+#[unstable = "uncertain about variadic generics, input versus associated types"]
+pub trait Fn<Args,Result> {
     /// This is called when the call operator is used.
     extern "rust-call" fn call(&self, args: Args) -> Result;
 }
 
 /// A version of the call operator that takes a mutable receiver.
 #[lang="fn_mut"]
-pub trait FnMut<Args,Result> for Sized? {
+#[unstable = "uncertain about variadic generics, input versus associated types"]
+pub trait FnMut<Args,Result> {
     /// This is called when the call operator is used.
     extern "rust-call" fn call_mut(&mut self, args: Args) -> Result;
 }
 
 /// A version of the call operator that takes a by-value receiver.
 #[lang="fn_once"]
+#[unstable = "uncertain about variadic generics, input versus associated types"]
 pub trait FnOnce<Args,Result> {
     /// This is called when the call operator is used.
     extern "rust-call" fn call_once(self, args: Args) -> Result;
 }
 
-impl<Sized? F,A,R> FnMut<A,R> for F
-    where F : Fn<A,R>
+impl<F: ?Sized, A, R> FnMut<A, R> for F
+    where F : Fn<A, R>
 {
     extern "rust-call" fn call_mut(&mut self, args: A) -> R {
         self.call(args)
index a9a1857ec97bf3764f91da9751ce60675447600d..39d0f024d4d4143f63c1419065d42481b8b5beb8 100644 (file)
@@ -807,6 +807,7 @@ impl<A> ExactSizeIterator for Item<A> {}
 #[stable]
 pub struct Iter<'a, A: 'a> { inner: Item<&'a A> }
 
+#[stable]
 impl<'a, A> Iterator for Iter<'a, A> {
     type Item = &'a A;
 
@@ -816,11 +817,13 @@ fn next(&mut self) -> Option<&'a A> { self.inner.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
 }
 
+#[stable]
 impl<'a, A> DoubleEndedIterator for Iter<'a, A> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a A> { self.inner.next_back() }
 }
 
+#[stable]
 impl<'a, A> ExactSizeIterator for Iter<'a, A> {}
 
 #[stable]
@@ -834,6 +837,7 @@ fn clone(&self) -> Iter<'a, A> {
 #[stable]
 pub struct IterMut<'a, A: 'a> { inner: Item<&'a mut A> }
 
+#[stable]
 impl<'a, A> Iterator for IterMut<'a, A> {
     type Item = &'a mut A;
 
@@ -843,17 +847,20 @@ fn next(&mut self) -> Option<&'a mut A> { self.inner.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
 }
 
+#[stable]
 impl<'a, A> DoubleEndedIterator for IterMut<'a, A> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a mut A> { self.inner.next_back() }
 }
 
+#[stable]
 impl<'a, A> ExactSizeIterator for IterMut<'a, A> {}
 
 /// An iterator over the item contained inside an Option.
 #[stable]
 pub struct IntoIter<A> { inner: Item<A> }
 
+#[stable]
 impl<A> Iterator for IntoIter<A> {
     type Item = A;
 
@@ -863,11 +870,13 @@ fn next(&mut self) -> Option<A> { self.inner.next() }
     fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
 }
 
+#[stable]
 impl<A> DoubleEndedIterator for IntoIter<A> {
     #[inline]
     fn next_back(&mut self) -> Option<A> { self.inner.next_back() }
 }
 
+#[stable]
 impl<A> ExactSizeIterator for IntoIter<A> {}
 
 /////////////////////////////////////////////////////////////////////////////
index d4aca1bb73c23659e987f6774abfc3c64708cef9..e88cb73c8a9b7f6f8d7b6f1a0a6c1207febc3f0d 100644 (file)
@@ -43,8 +43,7 @@
 pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 pub use iter::{Extend, IteratorExt};
 pub use iter::{Iterator, DoubleEndedIterator};
-pub use iter::{IteratorCloneExt, CloneIteratorExt};
-pub use iter::{IteratorOrdExt, ExactSizeIterator};
+pub use iter::{ExactSizeIterator};
 pub use option::Option::{self, Some, None};
 pub use ptr::{PtrExt, MutPtrExt};
 pub use result::Result::{self, Ok, Err};
index 3bef1d153637796e710920c34e84083eac39c9e6..5ef6f6b2623aa7c97ff6ba49d443a313a8e3b9e8 100644 (file)
@@ -20,7 +20,6 @@
 
 use kinds::Copy;
 use mem;
-use kinds::Sized;
 
 /// The representation of a Rust slice
 #[repr(C)]
@@ -52,7 +51,7 @@ pub struct TraitObject {
 
 /// This trait is meant to map equivalences between raw structs and their
 /// corresponding rust values.
-pub trait Repr<T> for Sized? {
+pub trait Repr<T> {
     /// This function "unwraps" a rust value (without consuming it) into its raw
     /// struct representation. This can be used to read/write different values
     /// for the struct. This is a safe method because by default it does not
index 7135faaa76516aa257ab14ea37f4cf44eeb179a9..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() { }
 //! ```
 //!
@@ -807,6 +807,7 @@ fn as_slice<'a>(&'a self) -> &'a [T] {
 #[stable]
 pub struct Iter<'a, T: 'a> { inner: Option<&'a T> }
 
+#[stable]
 impl<'a, T> Iterator for Iter<'a, T> {
     type Item = &'a T;
 
@@ -819,11 +820,13 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<'a, T> DoubleEndedIterator for Iter<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a T> { self.inner.take() }
 }
 
+#[stable]
 impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
 
 impl<'a, T> Clone for Iter<'a, T> {
@@ -834,6 +837,7 @@ fn clone(&self) -> Iter<'a, T> { Iter { inner: self.inner } }
 #[stable]
 pub struct IterMut<'a, T: 'a> { inner: Option<&'a mut T> }
 
+#[stable]
 impl<'a, T> Iterator for IterMut<'a, T> {
     type Item = &'a mut T;
 
@@ -846,17 +850,20 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a mut T> { self.inner.take() }
 }
 
+#[stable]
 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
 
 /// An iterator over the value in a `Ok` variant of a `Result`.
 #[stable]
 pub struct IntoIter<T> { inner: Option<T> }
 
+#[stable]
 impl<T> Iterator for IntoIter<T> {
     type Item = T;
 
@@ -869,11 +876,13 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<T> DoubleEndedIterator for IntoIter<T> {
     #[inline]
     fn next_back(&mut self) -> Option<T> { self.inner.take() }
 }
 
+#[stable]
 impl<T> ExactSizeIterator for IntoIter<T> {}
 
 /////////////////////////////////////////////////////////////////////////////
index 7aed16173e988bbd852cc1fd1566de977f297eb5..093ed0b242f5f4d5583f839a7534ee8e697d9912 100644 (file)
@@ -64,7 +64,7 @@
 
 /// Extension methods for slices.
 #[allow(missing_docs)] // docs in libcollections
-pub trait SliceExt for Sized? {
+pub trait SliceExt {
     type Item;
 
     fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [Self::Item];
@@ -614,7 +614,7 @@ fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T]
 
 /// Data that is viewable as a slice.
 #[experimental = "will be replaced by slice syntax"]
-pub trait AsSlice<T> for Sized? {
+pub trait AsSlice<T> {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a [T];
 }
@@ -626,13 +626,13 @@ fn as_slice<'a>(&'a self) -> &'a [T] { self }
 }
 
 #[experimental = "trait is experimental"]
-impl<'a, T, Sized? U: AsSlice<T>> AsSlice<T> for &'a U {
+impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a U {
     #[inline(always)]
     fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
 }
 
 #[experimental = "trait is experimental"]
-impl<'a, T, Sized? U: AsSlice<T>> AsSlice<T> for &'a mut U {
+impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U {
     #[inline(always)]
     fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
 }
@@ -650,7 +650,7 @@ fn default() -> &'a [T] { &[] }
 // The shared definition of the `Iter` and `IterMut` iterators
 macro_rules! iterator {
     (struct $name:ident -> $ptr:ty, $elem:ty) => {
-        #[experimental = "needs review"]
+        #[stable]
         impl<'a, T> Iterator for $name<'a, T> {
             type Item = $elem;
 
@@ -688,7 +688,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
             }
         }
 
-        #[experimental = "needs review"]
+        #[stable]
         impl<'a, T> DoubleEndedIterator for $name<'a, T> {
             #[inline]
             fn next_back(&mut self) -> Option<$elem> {
@@ -771,7 +771,7 @@ impl<'a,T> Copy for Iter<'a,T> {}
 
 iterator!{struct Iter -> *const T, &'a T}
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T> ExactSizeIterator for Iter<'a, T> {}
 
 #[stable]
@@ -779,7 +779,7 @@ impl<'a, T> Clone for Iter<'a, T> {
     fn clone(&self) -> Iter<'a, T> { *self }
 }
 
-#[experimental = "needs review"]
+#[experimental = "trait is experimental"]
 impl<'a, T> RandomAccessIterator for Iter<'a, T> {
     #[inline]
     fn indexable(&self) -> uint {
@@ -865,7 +865,7 @@ pub fn into_slice(self) -> &'a mut [T] {
 
 iterator!{struct IterMut -> *mut T, &'a mut T}
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
 
 /// An internal abstraction over the splitting iterators, so that
@@ -897,7 +897,7 @@ fn clone(&self) -> Split<'a, T, P> {
     }
 }
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T, P> Iterator for Split<'a, T, P> where P: FnMut(&T) -> bool {
     type Item = &'a [T];
 
@@ -925,7 +925,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T, P> DoubleEndedIterator for Split<'a, T, P> where P: FnMut(&T) -> bool {
     #[inline]
     fn next_back(&mut self) -> Option<&'a [T]> {
@@ -970,7 +970,7 @@ fn finish(&mut self) -> Option<&'a mut [T]> {
     }
 }
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T, P> Iterator for SplitMut<'a, T, P> where P: FnMut(&T) -> bool {
     type Item = &'a mut [T];
 
@@ -1005,7 +1005,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T, P> DoubleEndedIterator for SplitMut<'a, T, P> where
     P: FnMut(&T) -> bool,
 {
@@ -1038,7 +1038,6 @@ struct GenericSplitN<I> {
     invert: bool
 }
 
-#[experimental = "needs review"]
 impl<T, I: SplitIter + Iterator<Item=T>> Iterator for GenericSplitN<I> {
     type Item = T;
 
@@ -1061,6 +1060,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 
 /// An iterator over subslices separated by elements that match a predicate
 /// function, limited to a given number of splits.
+#[stable]
 pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
     inner: GenericSplitN<Split<'a, T, P>>
 }
@@ -1068,12 +1068,14 @@ pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
 /// An iterator over subslices separated by elements that match a
 /// predicate function, limited to a given number of splits, starting
 /// from the end of the slice.
+#[stable]
 pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool {
     inner: GenericSplitN<Split<'a, T, P>>
 }
 
 /// An iterator over subslices separated by elements that match a predicate
 /// function, limited to a given number of splits.
+#[stable]
 pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
     inner: GenericSplitN<SplitMut<'a, T, P>>
 }
@@ -1081,12 +1083,14 @@ pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
 /// An iterator over subslices separated by elements that match a
 /// predicate function, limited to a given number of splits, starting
 /// from the end of the slice.
+#[stable]
 pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool {
     inner: GenericSplitN<SplitMut<'a, T, P>>
 }
 
 macro_rules! forward_iterator {
     ($name:ident: $elem:ident, $iter_of:ty) => {
+        #[stable]
         impl<'a, $elem, P> Iterator for $name<'a, $elem, P> where
             P: FnMut(&T) -> bool
         {
@@ -1112,12 +1116,13 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 
 /// An iterator over overlapping subslices of length `size`.
 #[derive(Clone)]
-#[experimental = "needs review"]
+#[stable]
 pub struct Windows<'a, T:'a> {
     v: &'a [T],
     size: uint
 }
 
+#[stable]
 impl<'a, T> Iterator for Windows<'a, T> {
     type Item = &'a [T];
 
@@ -1149,13 +1154,13 @@ fn size_hint(&self) -> (uint, Option<uint>) {
 /// When the slice len is not evenly divided by the chunk size, the last slice
 /// of the iteration will be the remainder.
 #[derive(Clone)]
-#[experimental = "needs review"]
+#[stable]
 pub struct Chunks<'a, T:'a> {
     v: &'a [T],
     size: uint
 }
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T> Iterator for Chunks<'a, T> {
     type Item = &'a [T];
 
@@ -1184,7 +1189,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T> DoubleEndedIterator for Chunks<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a [T]> {
@@ -1200,7 +1205,7 @@ fn next_back(&mut self) -> Option<&'a [T]> {
     }
 }
 
-#[experimental = "needs review"]
+#[experimental = "trait is experimental"]
 impl<'a, T> RandomAccessIterator for Chunks<'a, T> {
     #[inline]
     fn indexable(&self) -> uint {
@@ -1224,13 +1229,13 @@ fn idx(&mut self, index: uint) -> Option<&'a [T]> {
 /// An iterator over a slice in (non-overlapping) mutable chunks (`size`
 /// elements at a time). When the slice len is not evenly divided by the chunk
 /// size, the last slice of the iteration will be the remainder.
-#[experimental = "needs review"]
+#[stable]
 pub struct ChunksMut<'a, T:'a> {
     v: &'a mut [T],
     chunk_size: uint
 }
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T> Iterator for ChunksMut<'a, T> {
     type Item = &'a mut [T];
 
@@ -1260,7 +1265,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-#[experimental = "needs review"]
+#[stable]
 impl<'a, T> DoubleEndedIterator for ChunksMut<'a, T> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a mut [T]> {
@@ -1338,7 +1343,7 @@ pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] {
 /// not being able to provide a non-aliasing guarantee of the returned mutable
 /// slice.
 #[inline]
-#[unstable = "jshould be renamed to from_raw_parts_mut"]
+#[unstable = "should be renamed to from_raw_parts_mut"]
 pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] {
     transmute(RawSlice { data: *p as *const T, len: len })
 }
@@ -1350,12 +1355,11 @@ pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] {
 /// Operations on `[u8]`.
 #[experimental = "needs review"]
 pub mod bytes {
-    use kinds::Sized;
     use ptr;
     use slice::SliceExt;
 
     /// A trait for operations on mutable `[u8]`s.
-    pub trait MutableByteVector for Sized? {
+    pub trait MutableByteVector {
         /// Sets all bytes of the receiver to the given value.
         fn set_memory(&mut self, value: u8);
     }
@@ -1439,7 +1443,7 @@ fn gt(&self, other: &[T]) -> bool {
 
 /// Extension methods for slices containing integers.
 #[experimental]
-pub trait IntSliceExt<U, S> for Sized? {
+pub trait IntSliceExt<U, S> {
     /// Converts the slice to an immutable slice of unsigned integers with the same width.
     fn as_unsigned<'a>(&'a self) -> &'a [U];
     /// Converts the slice to an immutable slice of signed integers with the same width.
index d069744f8da54f109bba4c957240999bbbfa8258..a39787b8207b5161c2fcbdb54c899d0829a93e11 100644 (file)
 macro_rules! delegate_iter {
     (exact $te:ty in $ti:ty) => {
         delegate_iter!{$te in $ti}
+        #[stable]
         impl<'a> ExactSizeIterator for $ti {
-            #[inline]
-            fn rposition<P>(&mut self, predicate: P) -> Option<uint> where P: FnMut($te) -> bool{
-                self.0.rposition(predicate)
-            }
             #[inline]
             fn len(&self) -> uint {
                 self.0.len()
@@ -49,6 +46,7 @@ fn len(&self) -> uint {
         }
     };
     ($te:ty in $ti:ty) => {
+        #[stable]
         impl<'a> Iterator for $ti {
             type Item = $te;
 
@@ -61,6 +59,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
                 self.0.size_hint()
             }
         }
+        #[stable]
         impl<'a> DoubleEndedIterator for $ti {
             #[inline]
             fn next_back(&mut self) -> Option<$te> {
@@ -69,6 +68,7 @@ fn next_back(&mut self) -> Option<$te> {
         }
     };
     (pattern $te:ty in $ti:ty) => {
+        #[stable]
         impl<'a, P: CharEq> Iterator for $ti {
             type Item = $te;
 
@@ -81,6 +81,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
                 self.0.size_hint()
             }
         }
+        #[stable]
         impl<'a, P: CharEq> DoubleEndedIterator for $ti {
             #[inline]
             fn next_back(&mut self) -> Option<$te> {
@@ -89,6 +90,7 @@ fn next_back(&mut self) -> Option<$te> {
         }
     };
     (pattern forward $te:ty in $ti:ty) => {
+        #[stable]
         impl<'a, P: CharEq> Iterator for $ti {
             type Item = $te;
 
@@ -142,6 +144,7 @@ fn from_str(s: &str) -> Option<bool> {
 
 /// Errors which can occur when attempting to interpret a byte slice as a `str`.
 #[derive(Copy, Eq, PartialEq, Clone)]
+#[unstable = "error enumeration recently added and definitions may be refined"]
 pub enum Utf8Error {
     /// An invalid byte was detected at the byte offset given.
     ///
@@ -165,6 +168,7 @@ pub enum Utf8Error {
 ///
 /// Returns `Err` if the slice is not utf-8 with a description as to why the
 /// provided slice is not utf-8.
+#[stable]
 pub fn from_utf8(v: &[u8]) -> Result<&str, Utf8Error> {
     try!(run_utf8_validation_iterator(&mut v.iter()));
     Ok(unsafe { from_utf8_unchecked(v) })
@@ -190,7 +194,7 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
 /// # Panics
 ///
 /// This function will panic if the string pointed to by `s` is not valid UTF-8.
-#[unstable = "may change location based on the outcome of the c_str module"]
+#[deprecated = "use std::ffi::c_str_to_bytes + str::from_utf8"]
 pub unsafe fn from_c_str(s: *const i8) -> &'static str {
     let s = s as *const u8;
     let mut len = 0u;
@@ -230,7 +234,7 @@ fn only_ascii(&self) -> bool { false }
 impl<'a> CharEq for &'a [char] {
     #[inline]
     fn matches(&mut self, c: char) -> bool {
-        self.iter().any(|&mut m| m.matches(c))
+        self.iter().any(|&m| { let mut m = m; m.matches(c) })
     }
 
     #[inline]
@@ -247,6 +251,7 @@ fn only_ascii(&self) -> bool {
 ///
 /// Created with the method `.chars()`.
 #[derive(Clone, Copy)]
+#[stable]
 pub struct Chars<'a> {
     iter: slice::Iter<'a, u8>
 }
@@ -275,6 +280,7 @@ fn unwrap_or_0(opt: Option<&u8>) -> u8 {
     }
 }
 
+#[stable]
 impl<'a> Iterator for Chars<'a> {
     type Item = char;
 
@@ -320,6 +326,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<'a> DoubleEndedIterator for Chars<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<char> {
@@ -356,11 +363,13 @@ fn next_back(&mut self) -> Option<char> {
 /// External iterator for a string's characters and their byte offsets.
 /// Use with the `std::iter` module.
 #[derive(Clone)]
+#[stable]
 pub struct CharIndices<'a> {
     front_offset: uint,
     iter: Chars<'a>,
 }
 
+#[stable]
 impl<'a> Iterator for CharIndices<'a> {
     type Item = (uint, char);
 
@@ -384,6 +393,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
+#[stable]
 impl<'a> DoubleEndedIterator for CharIndices<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<(uint, char)> {
@@ -465,6 +475,7 @@ fn get_end(&mut self) -> Option<&'a str> {
     }
 }
 
+#[stable]
 impl<'a, Sep: CharEq> Iterator for CharSplits<'a, Sep> {
     type Item = &'a str;
 
@@ -499,6 +510,7 @@ fn next(&mut self) -> Option<&'a str> {
     }
 }
 
+#[stable]
 impl<'a, Sep: CharEq> DoubleEndedIterator for CharSplits<'a, Sep> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a str> {
@@ -540,6 +552,7 @@ fn next_back(&mut self) -> Option<&'a str> {
     }
 }
 
+#[stable]
 impl<'a, Sep: CharEq> Iterator for CharSplitsN<'a, Sep> {
     type Item = &'a str;
 
@@ -848,6 +861,7 @@ fn new(haystack: &[u8], needle: &[u8]) -> Searcher {
 /// An iterator over the start and end indices of the matches of a
 /// substring within a larger string
 #[derive(Clone)]
+#[unstable = "type may be removed"]
 pub struct MatchIndices<'a> {
     // constants
     haystack: &'a str,
@@ -858,13 +872,14 @@ pub struct MatchIndices<'a> {
 /// An iterator over the substrings of a string separated by a given
 /// search string
 #[derive(Clone)]
-#[unstable = "Type might get removed"]
+#[unstable = "type may be removed"]
 pub struct SplitStr<'a> {
     it: MatchIndices<'a>,
     last_end: uint,
     finished: bool
 }
 
+#[stable]
 impl<'a> Iterator for MatchIndices<'a> {
     type Item = (uint, uint);
 
@@ -881,6 +896,7 @@ fn next(&mut self) -> Option<(uint, uint)> {
     }
 }
 
+#[stable]
 impl<'a> Iterator for SplitStr<'a> {
     type Item = &'a str;
 
@@ -948,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,
@@ -1056,8 +1073,7 @@ pub struct CharRange {
 Section: Trait implementations
 */
 
-#[allow(missing_docs)]
-pub mod traits {
+mod traits {
     use cmp::{Ordering, Ord, PartialEq, PartialOrd, Eq};
     use cmp::Ordering::{Less, Equal, Greater};
     use iter::IteratorExt;
@@ -1130,7 +1146,7 @@ fn slice_or_fail<'a>(&'a self, from: &uint, to: &uint) -> &'a str {
 #[unstable = "Instead of taking this bound generically, this trait will be \
               replaced with one of slicing syntax, deref coercions, or \
               a more generic conversion trait"]
-pub trait Str for Sized? {
+pub trait Str {
     /// Work with `self` as a slice.
     fn as_slice<'a>(&'a self) -> &'a str;
 }
@@ -1140,7 +1156,7 @@ impl Str for str {
     fn as_slice<'a>(&'a self) -> &'a str { self }
 }
 
-impl<'a, Sized? S> Str for &'a S where S: Str {
+impl<'a, S: ?Sized> Str for &'a S where S: Str {
     #[inline]
     fn as_slice(&self) -> &str { Str::as_slice(*self) }
 }
@@ -1171,7 +1187,7 @@ fn as_slice(&self) -> &str { Str::as_slice(*self) }
 
 /// Methods for string slices
 #[allow(missing_docs)]
-pub trait StrExt for Sized? {
+pub trait StrExt {
     // NB there are no docs here are they're all located on the StrExt trait in
     // libcollections, not here.
 
@@ -1586,6 +1602,7 @@ impl<'a> Default for &'a str {
     fn default() -> &'a str { "" }
 }
 
+#[stable]
 impl<'a> Iterator for Lines<'a> {
     type Item = &'a str;
 
@@ -1593,11 +1610,13 @@ impl<'a> Iterator for Lines<'a> {
     fn next(&mut self) -> Option<&'a str> { self.inner.next() }
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
-}
+
+#[stable]}
 impl<'a> DoubleEndedIterator for Lines<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a str> { self.inner.next_back() }
-}
+
+#[stable]}
 impl<'a> Iterator for LinesAny<'a> {
     type Item = &'a str;
 
@@ -1605,7 +1624,8 @@ impl<'a> Iterator for LinesAny<'a> {
     fn next(&mut self) -> Option<&'a str> { self.inner.next() }
     #[inline]
     fn size_hint(&self) -> (uint, Option<uint>) { self.inner.size_hint() }
-}
+
+#[stable]}
 impl<'a> DoubleEndedIterator for LinesAny<'a> {
     #[inline]
     fn next_back(&mut self) -> Option<&'a str> { self.inner.next_back() }
index 23f9be124dadb74f86c3ca5eee52eb2833e01a41..a4bafe754ffdd812c011fafbb03f6a02fb57494f 100644 (file)
@@ -16,7 +16,7 @@
 struct MyWriterHasher;
 
 impl Hasher<MyWriter> for MyWriterHasher {
-    fn hash<Sized? T: Hash<MyWriter>>(&self, value: &T) -> u64 {
+    fn hash<T: ?Sized + Hash<MyWriter>>(&self, value: &T) -> u64 {
         let mut state = MyWriter { hash: 0 };
         value.hash(&mut state);
         state.hash
index 2aa2a229f90fa16a322610e8965cdb69d266f09f..73db72d0313e6af1d527305e5061b3d145d226e8 100644 (file)
@@ -769,7 +769,7 @@ fn test_range_step_inclusive() {
 #[test]
 fn test_reverse() {
     let mut ys = [1i, 2, 3, 4, 5];
-    ys.iter_mut().reverse_();
+    ys.iter_mut().reverse_in_place();
     assert!(ys == [5, 4, 3, 2, 1]);
 }
 
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 aa1550ae5b874cfbfd5d08dfcfb82e4af1d4ccf9..6ac311fe4b646ae2f5d9a8ae5642a8b5f0fd6e11 100644 (file)
 #![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)]
+#![feature(unboxed_closures, associated_types)]
 
-#[cfg(test)] #[phase(plugin, link)] extern crate log;
+#[cfg(test)] #[macro_use] extern crate log;
 
 extern crate libc;
 
 use libc::{c_void, size_t, c_int};
-use std::c_vec::CVec;
+use std::ops::Deref;
 use std::ptr::Unique;
+use std::slice;
+
+pub struct Bytes {
+    ptr: Unique<u8>,
+    len: uint,
+}
+
+impl Deref for Bytes {
+    type Target = [u8];
+    fn deref(&self) -> &[u8] {
+        unsafe { slice::from_raw_mut_buf(&self.ptr.0, self.len) }
+    }
+}
+
+impl Drop for Bytes {
+    fn drop(&mut self) {
+        unsafe { libc::free(self.ptr.0 as *mut _); }
+    }
+}
 
 #[link(name = "miniz", kind = "static")]
 extern {
@@ -52,7 +71,7 @@ fn tinfl_decompress_mem_to_heap(psrc_buf: *const c_void,
 static TINFL_FLAG_PARSE_ZLIB_HEADER : c_int = 0x1; // parse zlib header and adler32 checksum
 static TDEFL_WRITE_ZLIB_HEADER : c_int = 0x01000; // write zlib header and adler32 checksum
 
-fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
+fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
     unsafe {
         let mut outsz : size_t = 0;
         let res = tdefl_compress_mem_to_heap(bytes.as_ptr() as *const _,
@@ -60,8 +79,8 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
                                              &mut outsz,
                                              flags);
         if !res.is_null() {
-            let res = Unique(res);
-            Some(CVec::new_with_dtor(res.0 as *mut u8, outsz as uint, move|:| libc::free(res.0)))
+            let res = Unique(res as *mut u8);
+            Some(Bytes { ptr: res, len: outsz as uint })
         } else {
             None
         }
@@ -69,16 +88,16 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
 }
 
 /// Compress a buffer, without writing any sort of header on the output.
-pub fn deflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
+pub fn deflate_bytes(bytes: &[u8]) -> Option<Bytes> {
     deflate_bytes_internal(bytes, LZ_NORM)
 }
 
 /// Compress a buffer, using a header that zlib can understand.
-pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
+pub fn deflate_bytes_zlib(bytes: &[u8]) -> Option<Bytes> {
     deflate_bytes_internal(bytes, LZ_NORM | TDEFL_WRITE_ZLIB_HEADER)
 }
 
-fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
+fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<Bytes> {
     unsafe {
         let mut outsz : size_t = 0;
         let res = tinfl_decompress_mem_to_heap(bytes.as_ptr() as *const _,
@@ -86,8 +105,8 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
                                                &mut outsz,
                                                flags);
         if !res.is_null() {
-            let res = Unique(res);
-            Some(CVec::new_with_dtor(res.0 as *mut u8, outsz as uint, move|:| libc::free(res.0)))
+            let res = Unique(res as *mut u8);
+            Some(Bytes { ptr: res, len: outsz as uint })
         } else {
             None
         }
@@ -95,12 +114,12 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option<CVec<u8>> {
 }
 
 /// Decompress a buffer, without parsing any sort of header on the input.
-pub fn inflate_bytes(bytes: &[u8]) -> Option<CVec<u8>> {
+pub fn inflate_bytes(bytes: &[u8]) -> Option<Bytes> {
     inflate_bytes_internal(bytes, 0)
 }
 
 /// Decompress a buffer that starts with a zlib header.
-pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option<CVec<u8>> {
+pub fn inflate_bytes_zlib(bytes: &[u8]) -> Option<Bytes> {
     inflate_bytes_internal(bytes, TINFL_FLAG_PARSE_ZLIB_HEADER)
 }
 
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 e3bcf70e8c82ffa833368efa65c3497587cde717..64cc490f4b163e7d7c1d841b3f85a69087c0f8f4 100644 (file)
@@ -587,7 +587,7 @@ fn indent<W:Writer>(w: &mut W) -> io::IoResult<()> {
 mod tests {
     use self::NodeLabels::*;
     use super::{Id, Labeller, Nodes, Edges, GraphWalk, render};
-    use super::LabelText::{mod, LabelStr, EscStr};
+    use super::LabelText::{self, LabelStr, EscStr};
     use std::io::IoResult;
     use std::borrow::IntoCow;
     use std::iter::repeat;
index 04aa6d1649538019d2ba85b10824ff0641fa1cd4..567fe04c5afbc659df4ccb13f6b344b385bdb969 100644 (file)
@@ -25,7 +25,7 @@
 
 // Note 2: Once Dynamically Sized Types (DST) lands, it might be
 // reasonable to replace this with something like `enum MaybeOwned<'a,
-// Sized? U>{ Owned(Box<U>), Borrowed(&'a U) }`; and then `U` could be
+// U: ?Sized>{ Owned(Box<U>), Borrowed(&'a U) }`; and then `U` could be
 // instantiated with `[T]` or `str`, etc.  Of course, that would imply
 // removing the `Growable` variant, which relates to note 1 above.
 // Alternatively, we might add `MaybeOwned` for the general case but
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 233d1c049f4e5e2bcdc69327f0c014a2e4069b98..5249e971439cddc2af07df55748bf657ffb5e552 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 = 3i;
@@ -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=10i, y=20i);
@@ -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 71ce882e98ca99c2f5d4a602f788221aad9ae53c..815fc0e7ec7ad399b078a165f09b0b37ae3237a4 100644 (file)
@@ -12,7 +12,6 @@
 
 use core::prelude::*;
 use core::num::Int;
-
 use {Rng, SeedableRng, Rand};
 
 const KEY_WORDS    : uint =  8; // 8 words for the 256-bit key
@@ -28,8 +27,7 @@
 ///
 /// [1]: D. J. Bernstein, [*ChaCha, a variant of
 /// Salsa20*](http://cr.yp.to/chacha.html)
-
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct ChaChaRng {
     buffer:  [u32; STATE_WORDS], // Internal buffer of output
     state:   [u32; STATE_WORDS], // Initial state
@@ -283,5 +281,15 @@ fn test_rng_true_values() {
                         0x11cfa18e, 0xd3c50049, 0x75c775f6, 0x434c6530,
                         0x2c5bad8f, 0x898881dc, 0x5f1c86d9, 0xc1f8e7f4));
     }
+
+    #[test]
+    fn test_rng_clone() {
+        let seed : &[_] = &[0u32; 8];
+        let mut rng: ChaChaRng = SeedableRng::from_seed(seed);
+        let mut clone = rng.clone();
+        for _ in range(0u, 16) {
+            assert_eq!(rng.next_u64(), clone.next_u64());
+        }
+    }
 }
 
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 53ae242c5e245e1050fa85d965b04e7a2fbbdcfd..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);
@@ -179,6 +180,13 @@ macro_rules! rngstepn(
     }
 }
 
+// Cannot be derived because [u32; 256] does not implement Clone
+impl Clone for IsaacRng {
+    fn clone(&self) -> IsaacRng {
+        *self
+    }
+}
+
 impl Rng for IsaacRng {
     #[inline]
     fn next_u32(&mut self) -> u32 {
@@ -294,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;
@@ -313,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];
@@ -334,7 +342,7 @@ macro_rules! memloop (
                         self.mem[i+6]=g; self.mem[i+7]=h;
                     }
                 }}
-            );
+            }
 
             memloop!(self.rsl);
             memloop!(self.mem);
@@ -359,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);
@@ -415,6 +425,13 @@ macro_rules! rngstepn(
     }
 }
 
+// Cannot be derived because [u32; 256] does not implement Clone
+impl Clone for Isaac64Rng {
+    fn clone(&self) -> Isaac64Rng {
+        *self
+    }
+}
+
 impl Rng for Isaac64Rng {
     // FIXME #7771: having next_u32 like this should be unnecessary
     #[inline]
@@ -485,6 +502,7 @@ fn rand<R: Rng>(other: &mut R) -> Isaac64Rng {
     }
 }
 
+
 #[cfg(test)]
 mod test {
     use std::prelude::v1::*;
@@ -594,4 +612,14 @@ fn test_rng_64_true_values() {
                         596345674630742204, 9947027391921273664, 11788097613744130851,
                         10391409374914919106));
     }
+
+    #[test]
+    fn test_rng_clone() {
+        let seed: &[_] = &[1, 23, 456, 7890, 12345];
+        let mut rng: Isaac64Rng = SeedableRng::from_seed(seed);
+        let mut clone = rng.clone();
+        for _ in range(0u, 16) {
+            assert_eq!(rng.next_u64(), clone.next_u64());
+        }
+    }
 }
index 0f8dbc78cde3272c8ee62d2da768f1e16abeb65f..c4dd08f9917e2dcbc95349b9449406adf91d3934 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::*;
 
@@ -243,7 +261,7 @@ fn gen_range<T: PartialOrd + SampleRange>(&mut self, low: T, high: T) -> T {
     /// println!("{}", rng.gen_weighted_bool(3));
     /// ```
     fn gen_weighted_bool(&mut self, n: uint) -> bool {
-        n == 0 || self.gen_range(0, n) == 0
+        n <= 1 || self.gen_range(0, n) == 0
     }
 
     /// Return an iterator of random characters from the set A-Z,a-z,0-9.
@@ -385,6 +403,7 @@ pub trait SeedableRng<Seed>: Rng {
 /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
 /// Statistical Software*. Vol. 8 (Issue 14).
 #[allow(missing_copy_implementations)]
+#[derive(Clone)]
 pub struct XorShiftRng {
     x: u32,
     y: u32,
@@ -392,17 +411,6 @@ pub struct XorShiftRng {
     w: u32,
 }
 
-impl Clone for XorShiftRng {
-    fn clone(&self) -> XorShiftRng {
-        XorShiftRng {
-            x: self.x,
-            y: self.y,
-            z: self.z,
-            w: self.w,
-        }
-    }
-}
-
 impl XorShiftRng {
     /// Creates a new XorShiftRng instance which is not seeded.
     ///
@@ -507,6 +515,7 @@ fn rand<R: Rng>(rng: &mut R) -> XorShiftRng {
 #[cfg(not(test))]
 mod std {
     pub use core::{option, fmt}; // panic!()
+    pub use core::clone; // derive Clone
     pub use core::kinds;
 }
 
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 6666a21c31feebb5e874e4ec3d5d84651ce97aa5..425e34cd9f0424b437b8eab9972519829e3a36b3 100644 (file)
@@ -546,20 +546,20 @@ fn check_expr(&mut self, cx: &Context, e: &ast::Expr) {
 }
 
 declare_lint! {
-    RAW_POINTER_DERIVING,
+    RAW_POINTER_DERIVE,
     Warn,
     "uses of #[derive] with raw pointers are rarely correct"
 }
 
-struct RawPtrDerivingVisitor<'a, 'tcx: 'a> {
+struct RawPtrDeriveVisitor<'a, 'tcx: 'a> {
     cx: &'a Context<'a, 'tcx>
 }
 
-impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDerivingVisitor<'a, 'tcx> {
+impl<'a, 'tcx, 'v> Visitor<'v> for RawPtrDeriveVisitor<'a, 'tcx> {
     fn visit_ty(&mut self, ty: &ast::Ty) {
         static MSG: &'static str = "use of `#[derive]` with a raw pointer";
         if let ast::TyPtr(..) = ty.node {
-            self.cx.span_lint(RAW_POINTER_DERIVING, ty.span, MSG);
+            self.cx.span_lint(RAW_POINTER_DERIVE, ty.span, MSG);
         }
         visit::walk_ty(self, ty);
     }
@@ -568,21 +568,21 @@ fn visit_expr(&mut self, _: &ast::Expr) {}
     fn visit_block(&mut self, _: &ast::Block) {}
 }
 
-pub struct RawPointerDeriving {
+pub struct RawPointerDerive {
     checked_raw_pointers: NodeSet,
 }
 
-impl RawPointerDeriving {
-    pub fn new() -> RawPointerDeriving {
-        RawPointerDeriving {
+impl RawPointerDerive {
+    pub fn new() -> RawPointerDerive {
+        RawPointerDerive {
             checked_raw_pointers: NodeSet::new(),
         }
     }
 }
 
-impl LintPass for RawPointerDeriving {
+impl LintPass for RawPointerDerive {
     fn get_lints(&self) -> LintArray {
-        lint_array!(RAW_POINTER_DERIVING)
+        lint_array!(RAW_POINTER_DERIVE)
     }
 
     fn check_item(&mut self, cx: &Context, item: &ast::Item) {
@@ -607,7 +607,7 @@ fn check_item(&mut self, cx: &Context, item: &ast::Item) {
         if !self.checked_raw_pointers.insert(item.id) { return }
         match item.node {
             ast::ItemStruct(..) | ast::ItemEnum(..) => {
-                let mut visitor = RawPtrDerivingVisitor { cx: cx };
+                let mut visitor = RawPtrDeriveVisitor { cx: cx };
                 visit::walk_item(&mut visitor, &*item);
             }
             _ => {}
@@ -666,6 +666,9 @@ fn check_attribute(&mut self, cx: &Context, attr: &ast::Attribute) {
             "must_use",
             "stable",
             "unstable",
+
+            // FIXME: #19470 this shouldn't be needed forever
+            "old_orphan_check",
         ];
 
         static CRATE_ATTRS: &'static [&'static str] = &[
index 69e5b4889c28837ab5169d956a944e0df09a3c7d..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,
@@ -208,7 +214,7 @@ macro_rules! add_lint_group ( ( $sess:ident, $name:expr, $($lint:ident),* ) => (
 
         add_builtin_with_new!(sess,
                               TypeLimits,
-                              RawPointerDeriving,
+                              RawPointerDerive,
                               MissingDoc,
         );
 
@@ -247,6 +253,7 @@ macro_rules! add_lint_group ( ( $sess:ident, $name:expr, $($lint:ident),* ) => (
         self.register_renamed("unknown_crate_type", "unknown_crate_types");
         self.register_renamed("variant_size_difference", "variant_size_differences");
         self.register_renamed("transmute_fat_ptr", "fat_ptr_transmutes");
+        self.register_renamed("raw_pointer_deriving", "raw_pointer_derive");
 
     }
 
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 2f4acaca4de4d3eda8f5f1223da3182d9bd89f15..ec0b80c3a5342f26b6af6563ab6a628b0f2810b1 100644 (file)
@@ -23,8 +23,8 @@
 use util::nodemap::{FnvHashMap, NodeMap};
 
 use std::cell::RefCell;
-use std::c_vec::CVec;
 use std::rc::Rc;
+use flate::Bytes;
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token::IdentInterner;
@@ -36,7 +36,7 @@
 pub type cnum_map = FnvHashMap<ast::CrateNum, ast::CrateNum>;
 
 pub enum MetadataBlob {
-    MetadataVec(CVec<u8>),
+    MetadataVec(Bytes),
     MetadataArchive(loader::ArchiveMetadata),
 }
 
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 c18bd421b3b077b61946b57b615bbefd756c892d..7c0645b4ca204037c451ef1c62f6232a7c547360 100644 (file)
 use syntax::diagnostic::SpanHandler;
 use util::fs;
 
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::cmp;
 use std::collections::{HashMap, HashSet};
 use std::io::fs::PathExtensions;
@@ -720,9 +720,8 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
         }
     }
     unsafe {
-        let mb = filename.with_c_str(|buf| {
-            llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf)
-        });
+        let buf = CString::from_slice(filename.as_vec());
+        let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
         if mb as int == 0 {
             return Err(format!("error reading library: '{}'",
                                filename.display()))
@@ -738,8 +737,9 @@ fn get_metadata_section_imp(is_osx: bool, filename: &Path) -> Result<MetadataBlo
         while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
             let mut name_buf = ptr::null();
             let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
-            let name = String::from_raw_buf_len(name_buf as *const u8,
-                                                name_len as uint);
+            let name = slice::from_raw_buf(&(name_buf as *const u8),
+                                           name_len as uint).to_vec();
+            let name = String::from_utf8(name).unwrap();
             debug!("get_metadata_section: name {}", name);
             if read_meta_section_name(is_osx) == name {
                 let cbuf = llvm::LLVMGetSectionContents(si.llsi);
index de81f307c4d7cfb5286672806ee9f29f784e7a8c..3c672d0fdb6fa01057a9d69af99c66ed51c8be7b 100644 (file)
@@ -119,7 +119,7 @@ fn pat(&mut self, pat: &ast::Pat, pred: CFGIndex) -> CFGIndex {
             }
 
             ast::PatBox(ref subpat) |
-            ast::PatRegion(ref subpat) |
+            ast::PatRegion(ref subpat, _) |
             ast::PatIdent(_, _, Some(ref subpat)) => {
                 let subpat_exit = self.pat(&**subpat, pred);
                 self.add_node(pat.id, &[subpat_exit])
index 2d9284846acf349060192a44454f7945c536ad9b..f2b9ecb5ec4322aa8af50c7a0d780aad0bee7682 100644 (file)
@@ -473,7 +473,7 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
             }
         }
 
-        ty::ty_rptr(_, ty::mt { ty, .. }) => {
+        ty::ty_rptr(_, ty::mt { ty, mutbl }) => {
             match ty.sty {
                ty::ty_vec(_, Some(n)) => match ctor {
                     &Single => {
@@ -493,7 +493,7 @@ fn construct_witness(cx: &MatchCheckCtxt, ctor: &Constructor,
 
                 _ => {
                     assert_eq!(pats_len, 1);
-                    ast::PatRegion(pats.nth(0).unwrap())
+                    ast::PatRegion(pats.nth(0).unwrap(), mutbl)
                 }
             }
         }
@@ -860,7 +860,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
         ast::PatTup(ref args) =>
             Some(args.iter().map(|p| &**p).collect()),
 
-        ast::PatBox(ref inner) | ast::PatRegion(ref inner) =>
+        ast::PatBox(ref inner) | ast::PatRegion(ref inner, _) =>
             Some(vec![&**inner]),
 
         ast::PatLit(ref expr) => {
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 c015c2307f65ed9f1169fb5fd63366635bccab2f..e58ff53b00cb9f91c3e644f39075e4a70a9d9166 100644 (file)
@@ -66,7 +66,8 @@
 use super::region_inference::ConcreteFailure;
 use super::region_inference::SubSupConflict;
 use super::region_inference::SupSupConflict;
-use super::region_inference::ParamBoundFailure;
+use super::region_inference::GenericBoundFailure;
+use super::region_inference::GenericKind;
 use super::region_inference::ProcessedErrors;
 use super::region_inference::SameRegions;
 
@@ -120,11 +121,11 @@ fn report_concrete_failure(&self,
                                sub: Region,
                                sup: Region);
 
-    fn report_param_bound_failure(&self,
-                                  origin: SubregionOrigin<'tcx>,
-                                  param_ty: ty::ParamTy,
-                                  sub: Region,
-                                  sups: Vec<Region>);
+    fn report_generic_bound_failure(&self,
+                                    origin: SubregionOrigin<'tcx>,
+                                    kind: GenericKind<'tcx>,
+                                    sub: Region,
+                                    sups: Vec<Region>);
 
     fn report_sub_sup_conflict(&self,
                                var_origin: RegionVariableOrigin,
@@ -175,8 +176,8 @@ fn report_region_errors(&self,
                     self.report_concrete_failure(origin, sub, sup);
                 }
 
-                ParamBoundFailure(origin, param_ty, sub, sups) => {
-                    self.report_param_bound_failure(origin, param_ty, sub, sups);
+                GenericBoundFailure(kind, param_ty, sub, sups) => {
+                    self.report_generic_bound_failure(kind, param_ty, sub, sups);
                 }
 
                 SubSupConflict(var_origin,
@@ -421,30 +422,35 @@ fn expected_found_str<T: UserString<'tcx> + Resolvable<'tcx>>(
                      found.user_string(self.tcx)))
     }
 
-    fn report_param_bound_failure(&self,
-                                  origin: SubregionOrigin<'tcx>,
-                                  param_ty: ty::ParamTy,
-                                  sub: Region,
-                                  _sups: Vec<Region>) {
-
+    fn report_generic_bound_failure(&self,
+                                    origin: SubregionOrigin<'tcx>,
+                                    bound_kind: GenericKind<'tcx>,
+                                    sub: Region,
+                                    _sups: Vec<Region>)
+    {
         // FIXME: it would be better to report the first error message
         // with the span of the parameter itself, rather than the span
         // where the error was detected. But that span is not readily
         // accessible.
 
+        let labeled_user_string = match bound_kind {
+            GenericKind::Param(ref p) =>
+                format!("the parameter type `{}`", p.user_string(self.tcx)),
+            GenericKind::Projection(ref p) =>
+                format!("the associated type `{}`", p.user_string(self.tcx)),
+        };
+
         match sub {
             ty::ReFree(ty::FreeRegion {bound_region: ty::BrNamed(..), ..}) => {
                 // Does the required lifetime have a nice name we can print?
                 self.tcx.sess.span_err(
                     origin.span(),
-                    format!(
-                        "the parameter type `{}` may not live long enough",
-                        param_ty.user_string(self.tcx))[]);
+                    format!("{} may not live long enough", labeled_user_string)[]);
                 self.tcx.sess.span_help(
                     origin.span(),
                     format!(
                         "consider adding an explicit lifetime bound `{}: {}`...",
-                        param_ty.user_string(self.tcx),
+                        bound_kind.user_string(self.tcx),
                         sub.user_string(self.tcx))[]);
             }
 
@@ -452,14 +458,12 @@ fn report_param_bound_failure(&self,
                 // Does the required lifetime have a nice name we can print?
                 self.tcx.sess.span_err(
                     origin.span(),
-                    format!(
-                        "the parameter type `{}` may not live long enough",
-                        param_ty.user_string(self.tcx))[]);
+                    format!("{} may not live long enough", labeled_user_string)[]);
                 self.tcx.sess.span_help(
                     origin.span(),
                     format!(
                         "consider adding an explicit lifetime bound `{}: 'static`...",
-                        param_ty.user_string(self.tcx))[]);
+                        bound_kind.user_string(self.tcx))[]);
             }
 
             _ => {
@@ -467,17 +471,16 @@ fn report_param_bound_failure(&self,
                 self.tcx.sess.span_err(
                     origin.span(),
                     format!(
-                        "the parameter type `{}` may not live long enough",
-                        param_ty.user_string(self.tcx))[]);
+                        "{} may not live long enough",
+                        labeled_user_string)[]);
                 self.tcx.sess.span_help(
                     origin.span(),
                     format!(
-                        "consider adding an explicit lifetime bound to `{}`",
-                        param_ty.user_string(self.tcx))[]);
+                        "consider adding an explicit lifetime bound for `{}`",
+                        bound_kind.user_string(self.tcx))[]);
                 note_and_explain_region(
                     self.tcx,
-                    format!("the parameter type `{}` must be valid for ",
-                            param_ty.user_string(self.tcx))[],
+                    format!("{} must be valid for ", labeled_user_string)[],
                     sub,
                     "...");
             }
index e1401898f7a79582985ff1a1ccd667ca9785f4c2..c2db81d311483b5e72d57be2921e26f39ce176bd 100644 (file)
@@ -20,6 +20,7 @@
 pub use self::fixup_err::*;
 pub use middle::ty::IntVarValue;
 pub use self::freshen::TypeFreshener;
+pub use self::region_inference::GenericKind;
 
 use middle::subst;
 use middle::subst::Substs;
@@ -382,19 +383,6 @@ pub fn mk_subr<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
     cx.region_vars.commit(snapshot);
 }
 
-pub fn verify_param_bound<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
-                                    origin: SubregionOrigin<'tcx>,
-                                    param_ty: ty::ParamTy,
-                                    a: ty::Region,
-                                    bs: Vec<ty::Region>) {
-    debug!("verify_param_bound({}, {} <: {})",
-           param_ty.repr(cx.tcx),
-           a.repr(cx.tcx),
-           bs.repr(cx.tcx));
-
-    cx.region_vars.verify_param_bound(origin, param_ty, a, bs);
-}
-
 pub fn mk_eqty<'a, 'tcx>(cx: &InferCtxt<'a, 'tcx>,
                          a_is_expected: bool,
                          origin: TypeOrigin,
@@ -1070,6 +1058,20 @@ pub fn replace_late_bound_regions_with_fresh_var<T>(
             value,
             |br, _| self.next_region_var(LateBoundRegion(span, br, lbrct)))
     }
+
+    /// See `verify_generic_bound` method in `region_inference`
+    pub fn verify_generic_bound(&self,
+                                origin: SubregionOrigin<'tcx>,
+                                kind: GenericKind<'tcx>,
+                                a: ty::Region,
+                                bs: Vec<ty::Region>) {
+        debug!("verify_generic_bound({}, {} <: {})",
+               kind.repr(self.tcx),
+               a.repr(self.tcx),
+               bs.repr(self.tcx));
+
+        self.region_vars.verify_generic_bound(origin, kind, a, bs);
+    }
 }
 
 impl<'tcx> TypeTrace<'tcx> {
index f0ee63c08e8b60a86f1cd6a7c5a354d37536133f..d30a6ff1cd9d5f1e5b5f1e97c711fa405674ce06 100644 (file)
@@ -22,7 +22,7 @@
 use super::{RegionVariableOrigin, SubregionOrigin, TypeTrace, MiscVariable};
 
 use middle::region;
-use middle::ty;
+use middle::ty::{self, Ty};
 use middle::ty::{BoundRegion, FreeRegion, Region, RegionVid};
 use middle::ty::{ReEmpty, ReStatic, ReInfer, ReFree, ReEarlyBound};
 use middle::ty::{ReLateBound, ReScope, ReVar, ReSkolemized, BrFresh};
@@ -30,7 +30,7 @@
 use middle::graph::{Direction, NodeIndex};
 use util::common::indenter;
 use util::nodemap::{FnvHashMap, FnvHashSet};
-use util::ppaux::Repr;
+use util::ppaux::{Repr, UserString};
 
 use std::cell::{Cell, RefCell};
 use std::cmp::Ordering::{self, Less, Greater, Equal};
@@ -61,12 +61,18 @@ pub enum Verify<'tcx> {
     // `b` are inference variables.
     VerifyRegSubReg(SubregionOrigin<'tcx>, Region, Region),
 
-    // VerifyParamBound(T, _, R, RS): The parameter type `T` must
-    // outlive the region `R`. `T` is known to outlive `RS`. Therefore
-    // verify that `R <= RS[i]` for some `i`. Inference variables may
-    // be involved (but this verification step doesn't influence
-    // inference).
-    VerifyParamBound(ty::ParamTy, SubregionOrigin<'tcx>, Region, Vec<Region>),
+    // VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
+    // associated type) must outlive the region `R`. `T` is known to
+    // outlive `RS`. Therefore verify that `R <= RS[i]` for some
+    // `i`. Inference variables may be involved (but this verification
+    // step doesn't influence inference).
+    VerifyGenericBound(GenericKind<'tcx>, SubregionOrigin<'tcx>, Region, Vec<Region>),
+}
+
+#[derive(Clone, Show, PartialEq, Eq)]
+pub enum GenericKind<'tcx> {
+    Param(ty::ParamTy),
+    Projection(ty::ProjectionTy<'tcx>),
 }
 
 #[derive(Copy, PartialEq, Eq, Hash)]
@@ -98,12 +104,12 @@ pub enum RegionResolutionError<'tcx> {
     /// `o` requires that `a <= b`, but this does not hold
     ConcreteFailure(SubregionOrigin<'tcx>, Region, Region),
 
-    /// `ParamBoundFailure(p, s, a, bs)
+    /// `GenericBoundFailure(p, s, a, bs)
     ///
-    /// The parameter type `p` must be known to outlive the lifetime
+    /// The parameter/assocated-type `p` must be known to outlive the lifetime
     /// `a`, but it is only known to outlive `bs` (and none of the
     /// regions in `bs` outlive `a`).
-    ParamBoundFailure(SubregionOrigin<'tcx>, ty::ParamTy, Region, Vec<Region>),
+    GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, Region, Vec<Region>),
 
     /// `SubSupConflict(v, sub_origin, sub_r, sup_origin, sup_r)`:
     ///
@@ -489,12 +495,13 @@ pub fn make_subregion(&self,
         }
     }
 
-    pub fn verify_param_bound(&self,
-                              origin: SubregionOrigin<'tcx>,
-                              param_ty: ty::ParamTy,
-                              sub: Region,
-                              sups: Vec<Region>) {
-        self.add_verify(VerifyParamBound(param_ty, origin, sub, sups));
+    /// See `Verify::VerifyGenericBound`
+    pub fn verify_generic_bound(&self,
+                                origin: SubregionOrigin<'tcx>,
+                                kind: GenericKind<'tcx>,
+                                sub: Region,
+                                sups: Vec<Region>) {
+        self.add_verify(VerifyGenericBound(kind, origin, sub, sups));
     }
 
     pub fn lub_regions(&self,
@@ -660,7 +667,7 @@ pub fn tainted(&self, mark: &RegionSnapshot, r0: Region) -> Vec<Region> {
                                     &mut result_set, r,
                                     a, b);
                             }
-                            VerifyParamBound(_, _, a, ref bs) => {
+                            VerifyGenericBound(_, _, a, ref bs) => {
                                 for &b in bs.iter() {
                                     consider_adding_bidirectional_edges(
                                         &mut result_set, r,
@@ -1211,7 +1218,7 @@ fn collect_concrete_region_errors(&self,
                     errors.push(ConcreteFailure((*origin).clone(), sub, sup));
                 }
 
-                VerifyParamBound(ref param_ty, ref origin, sub, ref sups) => {
+                VerifyGenericBound(ref kind, ref origin, sub, ref sups) => {
                     let sub = normalize(values, sub);
                     if sups.iter()
                            .map(|&sup| normalize(values, sup))
@@ -1223,8 +1230,8 @@ fn collect_concrete_region_errors(&self,
                     let sups = sups.iter().map(|&sup| normalize(values, sup))
                                           .collect();
                     errors.push(
-                        ParamBoundFailure(
-                            (*origin).clone(), *param_ty, sub, sups));
+                        GenericBoundFailure(
+                            (*origin).clone(), kind.clone(), sub, sups));
                 }
             }
         }
@@ -1584,8 +1591,8 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
             VerifyRegSubReg(_, ref a, ref b) => {
                 format!("VerifyRegSubReg({}, {})", a.repr(tcx), b.repr(tcx))
             }
-            VerifyParamBound(_, ref p, ref a, ref bs) => {
-                format!("VerifyParamBound({}, {}, {})",
+            VerifyGenericBound(_, ref p, ref a, ref bs) => {
+                format!("VerifyGenericBound({}, {}, {})",
                         p.repr(tcx), a.repr(tcx), bs.repr(tcx))
             }
         }
@@ -1624,3 +1631,32 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
                 self.origin.repr(tcx))
     }
 }
+
+impl<'tcx> Repr<'tcx> for GenericKind<'tcx> {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        match *self {
+            GenericKind::Param(ref p) => p.repr(tcx),
+            GenericKind::Projection(ref p) => p.repr(tcx),
+        }
+    }
+}
+
+impl<'tcx> UserString<'tcx> for GenericKind<'tcx> {
+    fn user_string(&self, tcx: &ty::ctxt<'tcx>) -> String {
+        match *self {
+            GenericKind::Param(ref p) => p.user_string(tcx),
+            GenericKind::Projection(ref p) => p.user_string(tcx),
+        }
+    }
+}
+
+impl<'tcx> GenericKind<'tcx> {
+    pub fn to_ty(&self, tcx: &ty::ctxt<'tcx>) -> Ty<'tcx> {
+        match *self {
+            GenericKind::Param(ref p) =>
+                p.to_ty(tcx),
+            GenericKind::Projection(ref p) =>
+                ty::mk_projection(tcx, p.trait_ref.clone(), p.item_name),
+        }
+    }
+}
index e3763689ef41a46f3995257b906979a4f2ef7ecd..a83416667abdc331eaf8534011977c4826e8fa00 100644 (file)
@@ -121,7 +121,7 @@ fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>, id: ast::Nod
         // However, it's not as simple as checking whether `T :
         // Sized`, because even if `T : Sized` does not hold, that
         // just means that `T` *may* not be sized.  After all, even a
-        // type parameter `Sized? T` could be bound to a sized
+        // type parameter `T: ?Sized` could be bound to a sized
         // type. (Issue #20116)
         //
         // To handle this, we first check for "interior" type
@@ -139,16 +139,16 @@ fn check_transmute(&self, span: Span, from: Ty<'tcx>, to: Ty<'tcx>, id: ast::Nod
         // exhaustively checking all possible combinations. Here are some examples:
         //
         // ```
-        // fn foo<T,U>() {
+        // fn foo<T, U>() {
         //     // T=int, U=int
         // }
         //
-        // fn bar<Sized? T,U>() {
+        // fn bar<T: ?Sized, U>() {
         //     // T=int, U=int
         //     // T=[int], U=int
         // }
         //
-        // fn baz<Sized? T, Sized?U>() {
+        // fn baz<T: ?Sized, U: ?Sized>() {
         //     // T=int, U=int
         //     // T=[int], U=int
         //     // T=int, U=[int]
index dd61db4270ce3499bf2642edd8779d37a38578fa..2b8c9b532e593270e035fbac2fde45769f3a6e42 100644 (file)
@@ -1235,8 +1235,10 @@ fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F)
             }
           }
 
-          ast::PatBox(ref subpat) | ast::PatRegion(ref subpat) => {
-            // @p1, ~p1, ref p1
+          ast::PatBox(ref subpat) | ast::PatRegion(ref subpat, _) => {
+            // box p1, &p1, &mut p1.  we can ignore the mutability of
+            // PatRegion since that information is already contained
+            // in the type.
             let subcmt = try!(self.cat_deref(pat, cmt, 0, false));
               try!(self.cat_pattern_(subcmt, &**subpat, op));
           }
index 55abe895183f1ba69b195846fca35bea20f51850..42b6e54420b409ed9e014e793f8e7e93e597a2a5 100644 (file)
@@ -14,7 +14,7 @@
 use super::{Obligation, ObligationCause};
 use super::util;
 
-use middle::subst::Subst;
+use middle::subst::{Subst};
 use middle::ty::{self, Ty};
 use middle::infer::InferCtxt;
 use std::collections::HashSet;
@@ -53,20 +53,20 @@ pub fn impl_can_satisfy(infcx: &InferCtxt,
 }
 
 #[allow(missing_copy_implementations)]
-pub enum OrphanCheckErr {
+pub enum OrphanCheckErr<'tcx> {
     NoLocalInputType,
-    UncoveredTypeParameter(ty::ParamTy),
+    UncoveredTy(Ty<'tcx>),
 }
 
 /// Checks the coherence orphan rules. `impl_def_id` should be the
 /// def-id of a trait impl. To pass, either the trait must be local, or else
 /// two conditions must be satisfied:
 ///
-/// 1. At least one of the input types must involve a local type.
-/// 2. All type parameters must be covered by a local type.
-pub fn orphan_check(tcx: &ty::ctxt,
-                    impl_def_id: ast::DefId)
-                    -> Result<(), OrphanCheckErr>
+/// 1. All type parameters in `Self` must be "covered" by some local type constructor.
+/// 2. Some local type must appear in `Self`.
+pub fn orphan_check<'tcx>(tcx: &ty::ctxt<'tcx>,
+                          impl_def_id: ast::DefId)
+                          -> Result<(), OrphanCheckErr<'tcx>>
 {
     debug!("impl_is_local({})", impl_def_id.repr(tcx));
 
@@ -82,31 +82,21 @@ pub fn orphan_check(tcx: &ty::ctxt,
         return Ok(());
     }
 
-    // Check condition 1: at least one type must be local.
-    if !trait_ref.input_types().iter().any(|&t| ty_reaches_local(tcx, t)) {
-        return Err(OrphanCheckErr::NoLocalInputType);
+    // Otherwise, check that (1) all type parameters are covered.
+    let covered_params = type_parameters_covered_by_ty(tcx, trait_ref.self_ty());
+    let all_params = type_parameters_reachable_from_ty(trait_ref.self_ty());
+    for &param in all_params.difference(&covered_params) {
+        return Err(OrphanCheckErr::UncoveredTy(param));
     }
 
-    // Check condition 2: type parameters must be "covered" by a local type.
-    let covered_params: HashSet<_> =
-        trait_ref.input_types().iter()
-                               .flat_map(|&t| type_parameters_covered_by_ty(tcx, t).into_iter())
-                               .collect();
-    let all_params: HashSet<_> =
-        trait_ref.input_types().iter()
-                               .flat_map(|&t| type_parameters_reachable_from_ty(t).into_iter())
-                               .collect();
-    for &param in all_params.difference(&covered_params) {
-        return Err(OrphanCheckErr::UncoveredTypeParameter(param));
+    // And (2) some local type appears.
+    if !trait_ref.self_ty().walk().any(|t| ty_is_local_constructor(tcx, t)) {
+        return Err(OrphanCheckErr::NoLocalInputType);
     }
 
     return Ok(());
 }
 
-fn ty_reaches_local<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
-    ty.walk().any(|t| ty_is_local_constructor(tcx, t))
-}
-
 fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
     debug!("ty_is_local_constructor({})", ty.repr(tcx));
 
@@ -153,8 +143,8 @@ fn ty_is_local_constructor<'tcx>(tcx: &ty::ctxt<'tcx>, ty: Ty<'tcx>) -> bool {
 }
 
 fn type_parameters_covered_by_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
-                                 ty: Ty<'tcx>)
-                                 -> HashSet<ty::ParamTy>
+                                       ty: Ty<'tcx>)
+                                       -> HashSet<Ty<'tcx>>
 {
     if ty_is_local_constructor(tcx, ty) {
         type_parameters_reachable_from_ty(ty)
@@ -164,14 +154,14 @@ fn type_parameters_covered_by_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
 }
 
 /// All type parameters reachable from `ty`
-fn type_parameters_reachable_from_ty<'tcx>(ty: Ty<'tcx>) -> HashSet<ty::ParamTy> {
+fn type_parameters_reachable_from_ty<'tcx>(ty: Ty<'tcx>) -> HashSet<Ty<'tcx>> {
     ty.walk()
-        .filter_map(|t| {
+        .filter(|&t| {
             match t.sty {
-                ty::ty_param(ref param_ty) => Some(param_ty.clone()),
-                _ => None,
+                // FIXME(#20590) straighten story about projection types
+                ty::ty_projection(..) | ty::ty_param(..) => true,
+                _ => false,
             }
         })
         .collect()
 }
-
index d5b41d238062890f21d32306e03e2036b4868d8d..65f7ad296db519855ac5cd625d79f7b11c972db7 100644 (file)
@@ -643,11 +643,12 @@ fn confirm_candidate<'cx,'tcx>(
             match impl_ty {
                 Some(ty) => (ty, impl_vtable.nested.to_vec()),
                 None => {
-                    selcx.tcx().sess.span_bug(
-                        obligation.cause.span,
-                        format!("impl `{}` did not contain projection for `{}`",
-                                impl_vtable.repr(selcx.tcx()),
-                                obligation.repr(selcx.tcx())).as_slice());
+                    // This means that the impl is missing a
+                    // definition for the associated type. This error
+                    // ought to be reported by the type checker method
+                    // `check_impl_items_against_trait`, so here we
+                    // just return ty_err.
+                    (selcx.tcx().types.err, vec!())
                 }
             }
         }
index ab8888f9a33ebd83dce4a5aa6a5164a7ede28a49..229d34fe4237c22df7a49a2cb08740c3f89c1fd7 100644 (file)
@@ -92,8 +92,8 @@ fn push(&mut self, predicate: &ty::Predicate<'tcx>) {
                 // Only keep those bounds that we haven't already
                 // seen.  This is necessary to prevent infinite
                 // recursion in some cases.  One common case is when
-                // people define `trait Sized { }` rather than `trait
-                // Sized for Sized? { }`.
+                // people define `trait Sized: Sized { }` rather than `trait
+                // Sized { }`.
                 predicates.retain(|r| self.visited.insert(r.clone()));
 
                 self.stack.push(StackEntry { position: 0,
index 7cda6c21853a3116b1d83d23e82c94afe3e9a833..c359233eca173cd4ad7b9fe05d76b6838a4bc6d4 100644 (file)
@@ -1776,6 +1776,10 @@ pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
         !self.regions.is_empty_in(space)
     }
 
+    pub fn is_empty(&self) -> bool {
+        self.types.is_empty() && self.regions.is_empty()
+    }
+
     pub fn to_bounds(&self, tcx: &ty::ctxt<'tcx>, substs: &Substs<'tcx>)
                      -> GenericBounds<'tcx> {
         GenericBounds {
@@ -6167,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 f9f899401b1754e5bb436e896ee6a805aafdb3ea..138f648049c73f748e6937474f7e94ff38054148 100644 (file)
@@ -105,6 +105,7 @@ pub struct Options {
     pub prints: Vec<PrintRequest>,
     pub cg: CodegenOptions,
     pub color: ColorConfig,
+    pub show_span: Option<String>,
     pub externs: HashMap<String, Vec<String>>,
     pub crate_name: Option<String>,
     /// An optional name to use as the crate for std during std injection,
@@ -211,6 +212,7 @@ pub fn basic_options() -> Options {
         prints: Vec::new(),
         cg: basic_codegen_options(),
         color: Auto,
+        show_span: None,
         externs: HashMap::new(),
         crate_name: None,
         alt_std_name: None,
@@ -259,7 +261,6 @@ macro_rules! debugging_opts {
         BORROWCK_STATS,
         NO_LANDING_PADS,
         DEBUG_LLVM,
-        SHOW_SPAN,
         COUNT_TYPE_SIZES,
         META_STATS,
         GC,
@@ -299,7 +300,6 @@ pub fn debugging_opts_map() -> Vec<(&'static str, &'static str, u64)> {
      ("no-landing-pads", "omit landing pads for unwinding",
       NO_LANDING_PADS),
      ("debug-llvm", "enable debug output from LLVM", DEBUG_LLVM),
-     ("show-span", "show spans for compiler debugging", SHOW_SPAN),
      ("count-type-sizes", "count the sizes of aggregate types",
       COUNT_TYPE_SIZES),
      ("meta-stats", "gather metadata statistics", META_STATS),
@@ -823,6 +823,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
                       `flowgraph=<nodeid>` (graphviz formatted flowgraph for node), or
                       `everybody_loops` (all function bodies replaced with `loop {}`).",
                      "TYPE"),
+        opt::opt_u("", "show-span", "Show spans for compiler debugging", "expr|pat|ty"),
         opt::flagopt("", "dep-info",
                  "Output dependency info to <filename> after compiling, \
                   in a format suitable for use by Makefiles", "FILENAME"),
@@ -1143,6 +1144,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         prints: prints,
         cg: cg,
         color: color,
+        show_span: None,
         externs: externs,
         crate_name: crate_name,
         alt_std_name: None,
index 770e8d73ec7614f70ceb16982a5bdd7f9838f72a..abb780615ae7b8170f6f8801dd660e3368417683 100644 (file)
@@ -201,8 +201,8 @@ pub fn lto(&self) -> bool {
     pub fn no_landing_pads(&self) -> bool {
         self.debugging_opt(config::NO_LANDING_PADS)
     }
-    pub fn show_span(&self) -> bool {
-        self.debugging_opt(config::SHOW_SPAN)
+    pub fn unstable_options(&self) -> bool {
+        self.debugging_opt(config::UNSTABLE_OPTIONS)
     }
     pub fn print_enum_sizes(&self) -> bool {
         self.debugging_opt(config::PRINT_ENUM_SIZES)
index 0da01cd358953581a9d9172fd09ff35104cc64fe..ee224d1ec80fe0361a1b52506accf6e55c1f08a4 100644 (file)
@@ -75,7 +75,7 @@ pub fn new() -> super::DefIdSet {
 pub struct FnvState(u64);
 
 impl Hasher<FnvState> for FnvHasher {
-    fn hash<Sized? T: Hash<FnvState>>(&self, t: &T) -> u64 {
+    fn hash<T: ?Sized + Hash<FnvState>>(&self, t: &T) -> u64 {
         let mut state = FnvState(0xcbf29ce484222325);
         t.hash(&mut state);
         let FnvState(ret) = state;
index e6ee16d1789c00fbd401f20ab5fd472b52e34e5c..8c2a9993004d99c4e6d96ff2ca49181aa2d5108f 100644 (file)
@@ -38,7 +38,7 @@
 use syntax::owned_slice::OwnedSlice;
 
 /// Produces a string suitable for debugging output.
-pub trait Repr<'tcx> for Sized? {
+pub trait Repr<'tcx> {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String;
 }
 
@@ -601,7 +601,7 @@ fn repr(&self, _tcx: &ctxt) -> String {
     }
 }
 
-impl<'a, 'tcx, Sized? T:Repr<'tcx>> Repr<'tcx> for &'a T {
+impl<'a, 'tcx, T: ?Sized +Repr<'tcx>> Repr<'tcx> for &'a T {
     fn repr(&self, tcx: &ctxt<'tcx>) -> String {
         Repr::repr(*self, tcx)
     }
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 9540c3fa3d7e817ff692ba791c255b916b1ca0c2..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;
@@ -146,8 +146,8 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input)
         println!("{}", json::as_json(&krate));
     }
 
-    if sess.show_span() {
-        syntax::show_span::run(sess.diagnostic(), &krate);
+    if let Some(ref s) = sess.opts.show_span {
+        syntax::show_span::run(sess.diagnostic(), s.as_slice(), &krate);
     }
 
     krate
@@ -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);
         }
     });
 
@@ -272,7 +273,6 @@ pub fn phase_2_configure_and_expand(sess: &Session,
             }
             let cfg = syntax::ext::expand::ExpansionConfig {
                 crate_name: crate_name.to_string(),
-                deriving_hash_type_parameter: sess.features.borrow().default_type_params,
                 enable_quotes: sess.features.borrow().quote,
                 recursion_limit: sess.recursion_limit.get(),
             };
@@ -352,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));
@@ -572,7 +572,7 @@ pub fn stop_after_phase_1(sess: &Session) -> bool {
         debug!("invoked with --parse-only, returning early from compile_input");
         return true;
     }
-    if sess.show_span() {
+    if sess.opts.show_span.is_some() {
         return true;
     }
     return sess.opts.debugging_opts & config::AST_JSON_NOEXPAND != 0;
index 983188c7090000e65b330cd0232f60fa5647b828..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;
@@ -134,7 +148,7 @@ fn run_compiler(args: &[String]) {
         _ => early_error("multiple input filenames provided")
     };
 
-    let sess = build_session(sopts, input_file_path, descriptions);
+    let mut sess = build_session(sopts, input_file_path, descriptions);
     let cfg = config::build_configuration(&sess);
     if print_crate_info(&sess, Some(&input), &odir, &ofile) {
         return
@@ -145,7 +159,7 @@ fn run_compiler(args: &[String]) {
         pretty::parse_pretty(&sess, a.as_slice(), false)
     });
     let pretty = if pretty.is_none() &&
-        sess.debugging_opt(config::UNSTABLE_OPTIONS) {
+        sess.unstable_options() {
             matches.opt_str("xpretty").map(|a| {
                 // extended with unstable pretty-print variants
                 pretty::parse_pretty(&sess, a.as_slice(), true)
@@ -162,6 +176,10 @@ fn run_compiler(args: &[String]) {
         None => {/* continue */ }
     }
 
+    if sess.unstable_options() {
+        sess.opts.show_span = matches.opt_str("show-span");
+    }
+
     let r = matches.opt_strs("Z");
     if r.contains(&("ls".to_string())) {
         match input {
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 53992d4567a34915148e2c9e87957e05cbc81517..d3555e4c0436354055399d04ab1cbb2f58995c97 100644 (file)
@@ -13,7 +13,7 @@
 use libc;
 use ArchiveRef;
 
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::mem;
 use std::raw;
 
@@ -30,9 +30,8 @@ impl ArchiveRO {
     /// raised.
     pub fn open(dst: &Path) -> Option<ArchiveRO> {
         unsafe {
-            let ar = dst.with_c_str(|dst| {
-                ::LLVMRustOpenArchive(dst)
-            });
+            let s = CString::from_slice(dst.as_vec());
+            let ar = ::LLVMRustOpenArchive(s.as_ptr());
             if ar.is_null() {
                 None
             } else {
@@ -45,9 +44,9 @@ pub fn open(dst: &Path) -> Option<ArchiveRO> {
     pub fn read<'a>(&'a self, file: &str) -> Option<&'a [u8]> {
         unsafe {
             let mut size = 0 as libc::size_t;
-            let ptr = file.with_c_str(|file| {
-                ::LLVMRustArchiveReadSection(self.ptr, file, &mut size)
-            });
+            let file = CString::from_slice(file.as_bytes());
+            let ptr = ::LLVMRustArchiveReadSection(self.ptr, file.as_ptr(),
+                                                   &mut size);
             if ptr.is_null() {
                 None
             } else {
index 2ec5f37634afb35474c708bae64d1e8e9538d023..8a9334be985f70b04d177ec6402b734bd4b066e3 100644 (file)
@@ -24,6 +24,7 @@
 #![feature(globs)]
 #![feature(link_args)]
 #![feature(unboxed_closures)]
+#![feature(old_orphan_check)]
 
 extern crate libc;
 
@@ -47,7 +48,7 @@
 pub use self::DiagnosticSeverity::*;
 pub use self::Linkage::*;
 
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::cell::RefCell;
 use std::{raw, mem};
 use libc::{c_uint, c_ushort, uint64_t, c_int, size_t, c_char};
@@ -2114,10 +2115,9 @@ fn drop(&mut self) {
 }
 
 pub fn mk_target_data(string_rep: &str) -> TargetData {
+    let string_rep = CString::from_slice(string_rep.as_bytes());
     TargetData {
-        lltd: string_rep.with_c_str(|buf| {
-            unsafe { LLVMCreateTargetData(buf) }
-        })
+        lltd: unsafe { LLVMCreateTargetData(string_rep.as_ptr()) }
     }
 }
 
index a2c86c3cdb7563a71a0e0905cd469c141ef67596..58102fe5629d9f43bc2656d609830f2451a0f68e 100644 (file)
 #![feature(globs, phase, slicing_syntax)]
 #![feature(rustc_diagnostic_macros)]
 #![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 c6488ec6638a3efe83d1a199c0d87277c592d5c0..f3e90c43a8414961bcdb979fb15f9dbada402d85 100644 (file)
@@ -20,7 +20,7 @@
 use libc;
 use flate;
 
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::iter;
 use std::mem;
 use std::num::Int;
@@ -139,9 +139,10 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
     }
 
     // Internalize everything but the reachable symbols of the current module
-    let cstrs: Vec<::std::c_str::CString> =
-        reachable.iter().map(|s| s.to_c_str()).collect();
-    let arr: Vec<*const libc::c_char> = cstrs.iter().map(|c| c.as_ptr()).collect();
+    let cstrs: Vec<CString> = reachable.iter().map(|s| {
+        CString::from_slice(s.as_bytes())
+    }).collect();
+    let arr: Vec<*const i8> = cstrs.iter().map(|c| c.as_ptr()).collect();
     let ptr = arr.as_ptr();
     unsafe {
         llvm::LLVMRustRunRestrictionPass(llmod,
@@ -164,7 +165,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
     unsafe {
         let pm = llvm::LLVMCreatePassManager();
         llvm::LLVMRustAddAnalysisPasses(tm, pm, llmod);
-        "verify".with_c_str(|s| llvm::LLVMRustAddPass(pm, s));
+        llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
 
         let builder = llvm::LLVMPassManagerBuilderCreate();
         llvm::LLVMPassManagerBuilderPopulateLTOPassManager(builder, pm,
@@ -172,7 +173,7 @@ pub fn run(sess: &session::Session, llmod: ModuleRef,
             /* RunInliner = */ True);
         llvm::LLVMPassManagerBuilderDispose(builder);
 
-        "verify".with_c_str(|s| llvm::LLVMRustAddPass(pm, s));
+        llvm::LLVMRustAddPass(pm, "verify\0".as_ptr() as *const _);
 
         time(sess.time_passes(), "LTO passes", (), |()|
              llvm::LLVMRunPassManager(pm, llmod));
index 33011d9e35c106b959033561f4c63b88e7fed919..98e2b4b9dddb575bbba99fe53160840f43c7d138 100644 (file)
@@ -22,7 +22,7 @@
 use syntax::diagnostic;
 use syntax::diagnostic::{Emitter, Handler, Level, mk_handler};
 
-use std::c_str::{ToCStr, CString};
+use std::ffi::{self, CString};
 use std::io::Command;
 use std::io::fs;
 use std::iter::Unfold;
@@ -32,7 +32,7 @@
 use std::sync::{Arc, Mutex};
 use std::sync::mpsc::channel;
 use std::thread;
-use libc::{c_uint, c_int, c_void};
+use libc::{self, c_uint, c_int, c_void};
 
 #[derive(Clone, Copy, PartialEq, PartialOrd, Ord, Eq)]
 pub enum OutputType {
@@ -49,8 +49,9 @@ pub fn llvm_err(handler: &diagnostic::Handler, msg: String) -> ! {
         if cstr == ptr::null() {
             handler.fatal(msg[]);
         } else {
-            let err = CString::new(cstr, true);
-            let err = String::from_utf8_lossy(err.as_bytes());
+            let err = ffi::c_str_to_bytes(&cstr);
+            let err = String::from_utf8_lossy(err.as_slice()).to_string();
+            libc::free(cstr as *mut _);
             handler.fatal(format!("{}: {}",
                                   msg[],
                                   err[])[]);
@@ -66,13 +67,12 @@ pub fn write_output_file(
         output: &Path,
         file_type: llvm::FileType) {
     unsafe {
-        output.with_c_str(|output| {
-            let result = llvm::LLVMRustWriteOutputFile(
-                    target, pm, m, output, file_type);
-            if !result {
-                llvm_err(handler, "could not write output".to_string());
-            }
-        })
+        let output = CString::from_slice(output.as_vec());
+        let result = llvm::LLVMRustWriteOutputFile(
+                target, pm, m, output.as_ptr(), file_type);
+        if !result {
+            llvm_err(handler, "could not write output".to_string());
+        }
     }
 }
 
@@ -221,28 +221,25 @@ fn create_target_machine(sess: &Session) -> TargetMachineRef {
     let triple = sess.target.target.llvm_target[];
 
     let tm = unsafe {
-        triple.with_c_str(|t| {
-            let cpu = match sess.opts.cg.target_cpu {
-                Some(ref s) => s[],
-                None => sess.target.target.options.cpu[]
-            };
-            cpu.with_c_str(|cpu| {
-                target_feature(sess).with_c_str(|features| {
-                    llvm::LLVMRustCreateTargetMachine(
-                        t, cpu, features,
-                        code_model,
-                        reloc_model,
-                        opt_level,
-                        true /* EnableSegstk */,
-                        use_softfp,
-                        no_fp_elim,
-                        !any_library && reloc_model == llvm::RelocPIC,
-                        ffunction_sections,
-                        fdata_sections,
-                    )
-                })
-            })
-        })
+        let triple = CString::from_slice(triple.as_bytes());
+        let cpu = match sess.opts.cg.target_cpu {
+            Some(ref s) => s.as_slice(),
+            None => sess.target.target.options.cpu.as_slice()
+        };
+        let cpu = CString::from_slice(cpu.as_bytes());
+        let features = CString::from_slice(target_feature(sess).as_bytes());
+        llvm::LLVMRustCreateTargetMachine(
+            triple.as_ptr(), cpu.as_ptr(), features.as_ptr(),
+            code_model,
+            reloc_model,
+            opt_level,
+            true /* EnableSegstk */,
+            use_softfp,
+            no_fp_elim,
+            !any_library && reloc_model == llvm::RelocPIC,
+            ffunction_sections,
+            fdata_sections,
+        )
     };
 
     if tm.is_null() {
@@ -371,8 +368,9 @@ struct HandlerFreeVars<'a> {
 
     match llvm::diagnostic::Diagnostic::unpack(info) {
         llvm::diagnostic::Optimization(opt) => {
-            let pass_name = CString::new(opt.pass_name, false);
-            let pass_name = pass_name.as_str().expect("got a non-UTF8 pass name from LLVM");
+            let pass_name = str::from_utf8(ffi::c_str_to_bytes(&opt.pass_name))
+                                .ok()
+                                .expect("got a non-UTF8 pass name from LLVM");
             let enabled = match cgcx.remark {
                 AllPasses => true,
                 SomePasses(ref v) => v.iter().any(|s| *s == pass_name),
@@ -416,9 +414,9 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
 
     if config.emit_no_opt_bc {
         let ext = format!("{}.no-opt.bc", name_extra);
-        output_names.with_extension(ext[]).with_c_str(|buf| {
-            llvm::LLVMWriteBitcodeToFile(llmod, buf);
-        })
+        let out = output_names.with_extension(ext.as_slice());
+        let out = CString::from_slice(out.as_vec());
+        llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
     match config.opt_level {
@@ -433,7 +431,8 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             // If we're verifying or linting, add them to the function pass
             // manager.
             let addpass = |&: pass: &str| {
-                pass.with_c_str(|s| llvm::LLVMRustAddPass(fpm, s))
+                let pass = CString::from_slice(pass.as_bytes());
+                llvm::LLVMRustAddPass(fpm, pass.as_ptr())
             };
             if !config.no_verify { assert!(addpass("verify")); }
 
@@ -445,12 +444,11 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
             }
 
             for pass in config.passes.iter() {
-                pass.with_c_str(|s| {
-                    if !llvm::LLVMRustAddPass(mpm, s) {
-                        cgcx.handler.warn(format!("unknown pass {}, ignoring",
-                                                  *pass)[]);
-                    }
-                })
+                let pass = CString::from_slice(pass.as_bytes());
+                if !llvm::LLVMRustAddPass(mpm, pass.as_ptr()) {
+                    cgcx.handler.warn(format!("unknown pass {}, ignoring",
+                                              pass).as_slice());
+                }
             }
 
             // Finally, run the actual optimization passes
@@ -470,9 +468,9 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
 
                     if config.emit_lto_bc {
                         let name = format!("{}.lto.bc", name_extra);
-                        output_names.with_extension(name[]).with_c_str(|buf| {
-                            llvm::LLVMWriteBitcodeToFile(llmod, buf);
-                        })
+                        let out = output_names.with_extension(name.as_slice());
+                        let out = CString::from_slice(out.as_vec());
+                        llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
                     }
                 },
                 _ => {},
@@ -504,18 +502,18 @@ unsafe fn with_codegen<F>(tm: TargetMachineRef,
 
     if config.emit_bc {
         let ext = format!("{}.bc", name_extra);
-        output_names.with_extension(ext[]).with_c_str(|buf| {
-            llvm::LLVMWriteBitcodeToFile(llmod, buf);
-        })
+        let out = output_names.with_extension(ext.as_slice());
+        let out = CString::from_slice(out.as_vec());
+        llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
     }
 
     time(config.time_passes, "codegen passes", (), |()| {
         if config.emit_ir {
             let ext = format!("{}.ll", name_extra);
-            output_names.with_extension(ext[]).with_c_str(|output| {
-                with_codegen(tm, llmod, config.no_builtins, |cpm| {
-                    llvm::LLVMRustPrintModule(cpm, llmod, output);
-                })
+            let out = output_names.with_extension(ext.as_slice());
+            let out = CString::from_slice(out.as_vec());
+            with_codegen(tm, llmod, config.no_builtins, |cpm| {
+                llvm::LLVMRustPrintModule(cpm, llmod, out.as_ptr());
             })
         }
 
@@ -995,7 +993,7 @@ unsafe fn configure_llvm(sess: &Session) {
     let mut llvm_args = Vec::new();
     {
         let mut add = |&mut : arg: &str| {
-            let s = arg.to_c_str();
+            let s = CString::from_slice(arg.as_bytes());
             llvm_args.push(s.as_ptr());
             llvm_c_strs.push(s);
         };
@@ -1083,7 +1081,7 @@ unsafe fn populate_llvm_passes(fpm: llvm::PassManagerRef,
 
     match opt {
         llvm::CodeGenLevelDefault | llvm::CodeGenLevelAggressive => {
-            "mergefunc".with_c_str(|s| llvm::LLVMRustAddPass(mpm, s));
+            llvm::LLVMRustAddPass(mpm, "mergefunc\0".as_ptr() as *const _);
         }
         _ => {}
     };
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 50cbe664b90798d07853a7b8a7647e02fcaca572..fed0931cab71d52f071ed5429356ce99ed19fbd9 100644 (file)
@@ -683,7 +683,7 @@ fn any_uniq_pat(m: &[Match], col: uint) -> bool {
 }
 
 fn any_region_pat(m: &[Match], col: uint) -> bool {
-    any_pat!(m, col, ast::PatRegion(_))
+    any_pat!(m, col, ast::PatRegion(..))
 }
 
 fn any_irrefutable_adt_pat(tcx: &ty::ctxt, m: &[Match], col: uint) -> bool {
@@ -1725,7 +1725,7 @@ fn bind_irrefutable_pat<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
             let llbox = Load(bcx, val);
             bcx = bind_irrefutable_pat(bcx, &**inner, llbox, cleanup_scope);
         }
-        ast::PatRegion(ref inner) => {
+        ast::PatRegion(ref inner, _) => {
             let loaded_val = Load(bcx, val);
             bcx = bind_irrefutable_pat(bcx, &**inner, loaded_val, cleanup_scope);
         }
index 5597e112f76d1727f05d08a1febd1a599d1bb023..f18d483f70328bd3389cdc527f445b729c6247ff 100644 (file)
@@ -20,9 +20,8 @@
 use trans::type_of;
 use trans::type_::Type;
 
-use std::c_str::ToCStr;
-use std::string::String;
 use syntax::ast;
+use std::ffi::CString;
 use libc::{c_uint, c_char};
 
 // Take an inline assembly expression and splat it out via LLVM
@@ -121,18 +120,16 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
         ast::AsmIntel => llvm::AD_Intel
     };
 
-    let r = ia.asm.get().with_c_str(|a| {
-        constraints.with_c_str(|c| {
-            InlineAsmCall(bcx,
-                          a,
-                          c,
-                          inputs[],
+    let asm = CString::from_slice(ia.asm.get().as_bytes());
+    let constraints = CString::from_slice(constraints.as_bytes());
+    let r = InlineAsmCall(bcx,
+                          asm.as_ptr(),
+                          constraints.as_ptr(),
+                          inputs.as_slice(),
                           output_type,
                           ia.volatile,
                           ia.alignstack,
-                          dialect)
-        })
-    });
+                          dialect);
 
     // Again, based on how many outputs we have
     if num_outputs == 1 {
index 56c1e2ddba0b58f2b9350c411ac15aabab22ae40..edcfaae0f802d32482aab9ca1f785b2d142d7999 100644 (file)
 
 use arena::TypedArena;
 use libc::{c_uint, uint64_t};
-use std::c_str::ToCStr;
+use std::ffi::{self, CString};
 use std::cell::{Cell, RefCell};
 use std::collections::HashSet;
 use std::mem;
 use std::rc::Rc;
+use std::str;
 use std::{i8, i16, i32, i64};
 use syntax::abi::{Rust, RustCall, RustIntrinsic, Abi};
 use syntax::ast_util::local_def;
@@ -187,11 +188,10 @@ fn drop(&mut self) {
 pub fn decl_fn(ccx: &CrateContext, name: &str, cc: llvm::CallConv,
                ty: Type, output: ty::FnOutput) -> ValueRef {
 
-    let llfn: ValueRef = name.with_c_str(|buf| {
-        unsafe {
-            llvm::LLVMGetOrInsertFunction(ccx.llmod(), buf, ty.to_ref())
-        }
-    });
+    let buf = CString::from_slice(name.as_bytes());
+    let llfn: ValueRef = unsafe {
+        llvm::LLVMGetOrInsertFunction(ccx.llmod(), buf.as_ptr(), ty.to_ref())
+    };
 
     // diverging functions may unwind, but can never return normally
     if output == ty::FnDiverging {
@@ -331,9 +331,8 @@ pub fn get_extern_const<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, did: ast::DefId,
         None => ()
     }
     unsafe {
-        let c = name.with_c_str(|buf| {
-            llvm::LLVMAddGlobal(ccx.llmod(), ty.to_ref(), buf)
-        });
+        let buf = CString::from_slice(name.as_bytes());
+        let c = llvm::LLVMAddGlobal(ccx.llmod(), ty.to_ref(), buf.as_ptr());
         // Thread-local statics in some other crate need to *always* be linked
         // against in a thread-local fashion, so we need to be sure to apply the
         // thread-local attribute locally if it was present remotely. If we
@@ -472,15 +471,17 @@ pub fn set_always_inline(f: ValueRef) {
 }
 
 pub fn set_split_stack(f: ValueRef) {
-    "split-stack".with_c_str(|buf| {
-        unsafe { llvm::LLVMAddFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
-    })
+    unsafe {
+        llvm::LLVMAddFunctionAttrString(f, llvm::FunctionIndex as c_uint,
+                                        "split-stack\0".as_ptr() as *const _);
+    }
 }
 
 pub fn unset_split_stack(f: ValueRef) {
-    "split-stack".with_c_str(|buf| {
-        unsafe { llvm::LLVMRemoveFunctionAttrString(f, llvm::FunctionIndex as c_uint, buf); }
-    })
+    unsafe {
+        llvm::LLVMRemoveFunctionAttrString(f, llvm::FunctionIndex as c_uint,
+                                           "split-stack\0".as_ptr() as *const _);
+    }
 }
 
 // Double-check that we never ask LLVM to declare the same symbol twice. It
@@ -534,11 +535,8 @@ pub fn get_res_dtor<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
 // Structural comparison: a rather involved form of glue.
 pub fn maybe_name_value(cx: &CrateContext, v: ValueRef, s: &str) {
     if cx.sess().opts.cg.save_temps {
-        s.with_c_str(|buf| {
-            unsafe {
-                llvm::LLVMSetValueName(v, buf)
-            }
-        })
+        let buf = CString::from_slice(s.as_bytes());
+        unsafe { llvm::LLVMSetValueName(v, buf.as_ptr()) }
     }
 }
 
@@ -2639,11 +2637,10 @@ fn create_entry_fn(ccx: &CrateContext,
             unsafe { llvm::LLVMRustSetDLLExportStorageClass(llfn) }
         }
 
-        let llbb = "top".with_c_str(|buf| {
-            unsafe {
-                llvm::LLVMAppendBasicBlockInContext(ccx.llcx(), llfn, buf)
-            }
-        });
+        let llbb = unsafe {
+            llvm::LLVMAppendBasicBlockInContext(ccx.llcx(), llfn,
+                                                "top\0".as_ptr() as *const _)
+        };
         let bld = ccx.raw_builder();
         unsafe {
             llvm::LLVMPositionBuilderAtEnd(bld, llbb);
@@ -2664,9 +2661,9 @@ fn create_entry_fn(ccx: &CrateContext,
                 };
 
                 let args = {
-                    let opaque_rust_main = "rust_main".with_c_str(|buf| {
-                        llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p(ccx).to_ref(), buf)
-                    });
+                    let opaque_rust_main = llvm::LLVMBuildPointerCast(bld,
+                        rust_main, Type::i8p(ccx).to_ref(),
+                        "rust_main\0".as_ptr() as *const _);
 
                     vec!(
                         opaque_rust_main,
@@ -2773,9 +2770,9 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                                 format!("Illegal null byte in export_name \
                                          value: `{}`", sym)[]);
                         }
-                        let g = sym.with_c_str(|buf| {
-                            llvm::LLVMAddGlobal(ccx.llmod(), llty, buf)
-                        });
+                        let buf = CString::from_slice(sym.as_bytes());
+                        let g = llvm::LLVMAddGlobal(ccx.llmod(), llty,
+                                                    buf.as_ptr());
 
                         if attr::contains_name(i.attrs[],
                                                "thread_local") {
@@ -2817,9 +2814,8 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
                                                  sect.get())[]);
                     }
                     unsafe {
-                        sect.get().with_c_str(|buf| {
-                            llvm::LLVMSetSection(v, buf);
-                        })
+                        let buf = CString::from_slice(sect.get().as_bytes());
+                        llvm::LLVMSetSection(v, buf.as_ptr());
                     }
                 },
                 None => ()
@@ -2986,17 +2982,16 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
     let name = format!("rust_metadata_{}_{}",
                        cx.link_meta().crate_name,
                        cx.link_meta().crate_hash);
-    let llglobal = name.with_c_str(|buf| {
-        unsafe {
-            llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(), buf)
-        }
-    });
+    let buf = CString::from_vec(name.into_bytes());
+    let llglobal = unsafe {
+        llvm::LLVMAddGlobal(cx.metadata_llmod(), val_ty(llconst).to_ref(),
+                            buf.as_ptr())
+    };
     unsafe {
         llvm::LLVMSetInitializer(llglobal, llconst);
         let name = loader::meta_section_name(cx.sess().target.target.options.is_like_osx);
-        name.with_c_str(|buf| {
-            llvm::LLVMSetSection(llglobal, buf)
-        });
+        let name = CString::from_slice(name.as_bytes());
+        llvm::LLVMSetSection(llglobal, name.as_ptr())
     }
     return metadata;
 }
@@ -3004,8 +2999,6 @@ pub fn write_metadata(cx: &SharedCrateContext, krate: &ast::Crate) -> Vec<u8> {
 /// Find any symbols that are defined in one compilation unit, but not declared
 /// in any other compilation unit.  Give these symbols internal linkage.
 fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
-    use std::c_str::CString;
-
     unsafe {
         let mut declared = HashSet::new();
 
@@ -3035,7 +3028,8 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
                     continue
                 }
 
-                let name = CString::new(llvm::LLVMGetValueName(val), false);
+                let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val))
+                               .to_vec();
                 declared.insert(name);
             }
         }
@@ -3051,9 +3045,10 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
                     continue
                 }
 
-                let name = CString::new(llvm::LLVMGetValueName(val), false);
+                let name = ffi::c_str_to_bytes(&llvm::LLVMGetValueName(val))
+                               .to_vec();
                 if !declared.contains(&name) &&
-                   !reachable.contains(name.as_str().unwrap()) {
+                   !reachable.contains(str::from_utf8(name.as_slice()).unwrap()) {
                     llvm::SetLinkage(val, llvm::InternalLinkage);
                 }
             }
index 97f0b92a290f839ab9871f6819dce94038bef53f..e09d36ddae923188be8407e9942c2aac077713ec 100644 (file)
@@ -20,7 +20,8 @@
 use trans::type_::Type;
 use util::nodemap::FnvHashMap;
 use libc::{c_uint, c_char};
-use std::c_str::ToCStr;
+
+use std::ffi::CString;
 use syntax::codemap::Span;
 
 pub struct Builder<'a, 'tcx: 'a> {
@@ -429,9 +430,9 @@ pub fn alloca(&self, ty: Type, name: &str) -> ValueRef {
             if name.is_empty() {
                 llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
             } else {
-                name.with_c_str(|c| {
-                    llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), c)
-                })
+                let name = CString::from_slice(name.as_bytes());
+                llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(),
+                                      name.as_ptr())
             }
         }
     }
@@ -774,12 +775,12 @@ pub fn add_comment(&self, text: &str) {
             let comment_text = format!("{} {}", "#",
                                        sanitized.replace("\n", "\n\t# "));
             self.count_insn("inlineasm");
-            let asm = comment_text.with_c_str(|c| {
-                unsafe {
-                    llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(),
-                                             c, noname(), False, False)
-                }
-            });
+            let comment_text = CString::from_vec(comment_text.into_bytes());
+            let asm = unsafe {
+                llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.ccx)).to_ref(),
+                                         comment_text.as_ptr(), noname(), False,
+                                         False)
+            };
             self.call(asm, &[], None);
         }
     }
@@ -926,9 +927,8 @@ pub fn trap(&self) {
             let bb: BasicBlockRef = llvm::LLVMGetInsertBlock(self.llbuilder);
             let fn_: ValueRef = llvm::LLVMGetBasicBlockParent(bb);
             let m: ModuleRef = llvm::LLVMGetGlobalParent(fn_);
-            let t: ValueRef = "llvm.trap".with_c_str(|buf| {
-                llvm::LLVMGetNamedFunction(m, buf)
-            });
+            let p = "llvm.trap\0".as_ptr();
+            let t: ValueRef = llvm::LLVMGetNamedFunction(m, p as *const _);
             assert!((t as int != 0));
             let args: &[ValueRef] = &[];
             self.count_insn("trap");
index f59d152fa473cf5b88a8a4e1f63626ba341225e8..9ec0c822bf5fe4acc92a27aaddf00194d08d8a1d 100644 (file)
@@ -63,7 +63,7 @@ fn is_sse(&self) -> bool {
     }
 }
 
-trait ClassList for Sized? {
+trait ClassList {
     fn is_pass_byval(&self) -> bool;
     fn is_ret_bysret(&self) -> bool;
 }
index e8dee19ed54c1f7acb82f645b2e3574391d211d0..094f98e988aad202fda3fc3e9535f62c1a3cdcaa 100644 (file)
@@ -44,7 +44,7 @@
 
 use arena::TypedArena;
 use libc::{c_uint, c_char};
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::cell::{Cell, RefCell};
 use std::vec::Vec;
 use syntax::ast::Ident;
@@ -401,9 +401,8 @@ pub fn get_llreturn(&self) -> BasicBlockRef {
         if self.llreturn.get().is_none() {
 
             self.llreturn.set(Some(unsafe {
-                "return".with_c_str(|buf| {
-                    llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(), self.llfn, buf)
-                })
+                llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(), self.llfn,
+                                                    "return\0".as_ptr() as *const _)
             }))
         }
 
@@ -429,11 +428,10 @@ pub fn new_block(&'a self,
                      opt_node_id: Option<ast::NodeId>)
                      -> Block<'a, 'tcx> {
         unsafe {
-            let llbb = name.with_c_str(|buf| {
-                    llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
-                                                        self.llfn,
-                                                        buf)
-                });
+            let name = CString::from_slice(name.as_bytes());
+            let llbb = llvm::LLVMAppendBasicBlockInContext(self.ccx.llcx(),
+                                                           self.llfn,
+                                                           name.as_ptr());
             BlockS::new(llbb, is_lpad, opt_node_id, self)
         }
     }
@@ -708,7 +706,8 @@ pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef {
 
 pub fn C_floating(s: &str, t: Type) -> ValueRef {
     unsafe {
-        s.with_c_str(|buf| llvm::LLVMConstRealOfString(t.to_ref(), buf))
+        let s = CString::from_slice(s.as_bytes());
+        llvm::LLVMConstRealOfString(t.to_ref(), s.as_ptr())
     }
 }
 
@@ -789,9 +788,8 @@ pub fn C_cstr(cx: &CrateContext, s: InternedString, null_terminated: bool) -> Va
                                                 !null_terminated as Bool);
 
         let gsym = token::gensym("str");
-        let g = format!("str{}", gsym.uint()).with_c_str(|buf| {
-            llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf)
-        });
+        let buf = CString::from_vec(format!("str{}", gsym.uint()).into_bytes());
+        let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(sc).to_ref(), buf.as_ptr());
         llvm::LLVMSetInitializer(g, sc);
         llvm::LLVMSetGlobalConstant(g, True);
         llvm::SetLinkage(g, llvm::InternalLinkage);
@@ -815,9 +813,10 @@ pub fn C_binary_slice(cx: &CrateContext, data: &[u8]) -> ValueRef {
         let lldata = C_bytes(cx, data);
 
         let gsym = token::gensym("binary");
-        let g = format!("binary{}", gsym.uint()).with_c_str(|buf| {
-            llvm::LLVMAddGlobal(cx.llmod(), val_ty(lldata).to_ref(), buf)
-        });
+        let name = format!("binary{}", gsym.uint());
+        let name = CString::from_vec(name.into_bytes());
+        let g = llvm::LLVMAddGlobal(cx.llmod(), val_ty(lldata).to_ref(),
+                                    name.as_ptr());
         llvm::LLVMSetInitializer(g, lldata);
         llvm::LLVMSetGlobalConstant(g, True);
         llvm::SetLinkage(g, llvm::InternalLinkage);
index 7e47c8f3b959a277c5ef21856a0f2a7cf429201c..a3861e71d83de56c614d8c676c5a203167d1065e 100644 (file)
@@ -24,7 +24,6 @@
 use middle::ty::{self, Ty};
 use util::ppaux::{Repr, ty_to_string};
 
-use std::c_str::ToCStr;
 use std::iter::repeat;
 use libc::c_uint;
 use syntax::{ast, ast_util};
@@ -103,9 +102,8 @@ fn const_vec(cx: &CrateContext, e: &ast::Expr,
 
 pub fn const_addr_of(cx: &CrateContext, cv: ValueRef, mutbl: ast::Mutability) -> ValueRef {
     unsafe {
-        let gv = "const".with_c_str(|name| {
-            llvm::LLVMAddGlobal(cx.llmod(), val_ty(cv).to_ref(), name)
-        });
+        let gv = llvm::LLVMAddGlobal(cx.llmod(), val_ty(cv).to_ref(),
+                                     "const\0".as_ptr() as *const _);
         llvm::LLVMSetInitializer(gv, cv);
         llvm::LLVMSetGlobalConstant(gv,
                                     if mutbl == ast::MutImmutable {True} else {False});
index e5a0e2e9234d5ed1b022736dabc0f7e57abe243e..3726cf14023ee35c88ac7b05af5cbe377ff75b87 100644 (file)
@@ -29,8 +29,8 @@
 use util::sha2::Sha256;
 use util::nodemap::{NodeMap, NodeSet, DefIdMap, FnvHashMap, FnvHashSet};
 
+use std::ffi::CString;
 use std::cell::{Cell, RefCell};
-use std::c_str::ToCStr;
 use std::ptr;
 use std::rc::Rc;
 use syntax::ast;
@@ -221,21 +221,16 @@ fn next(&mut self) -> Option<(CrateContext<'a, 'tcx>, bool)> {
 
 unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextRef, ModuleRef) {
     let llcx = llvm::LLVMContextCreate();
-    let llmod = mod_name.with_c_str(|buf| {
-        llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
-    });
-    sess.target
-        .target
-        .data_layout
-        .with_c_str(|buf| {
-        llvm::LLVMSetDataLayout(llmod, buf);
-    });
-    sess.target
-        .target
-        .llvm_target
-        .with_c_str(|buf| {
-        llvm::LLVMRustSetNormalizedTarget(llmod, buf);
-    });
+    let mod_name = CString::from_slice(mod_name.as_bytes());
+    let llmod = llvm::LLVMModuleCreateWithNameInContext(mod_name.as_ptr(), llcx);
+
+    let data_layout = sess.target.target.data_layout.as_slice();
+    let data_layout = CString::from_slice(data_layout.as_bytes());
+    llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
+
+    let llvm_target = sess.target.target.llvm_target.as_slice();
+    let llvm_target = CString::from_slice(llvm_target.as_bytes());
+    llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
     (llcx, llmod)
 }
 
@@ -741,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(
@@ -759,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);
@@ -883,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!
@@ -896,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 84ae088f5beae449280971476cf4ec4225dd2ab2..3f0f7fd9bd3032564c37beff27febf777b1aecb3 100644 (file)
 use util::ppaux;
 
 use libc::c_uint;
-use std::c_str::{CString, ToCStr};
+use std::ffi::CString;
 use std::cell::{Cell, RefCell};
 use std::ptr;
 use std::rc::{Rc, Weak};
@@ -755,14 +755,15 @@ pub fn finalize(cx: &CrateContext) {
         // for OS X to understand. For more info see #11352
         // This can be overridden using --llvm-opts -dwarf-version,N.
         if cx.sess().target.target.options.is_like_osx {
-            "Dwarf Version".with_c_str(
-                |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s, 2));
+            llvm::LLVMRustAddModuleFlag(cx.llmod(),
+                                        "Dwarf Version\0".as_ptr() as *const _,
+                                        2)
         }
 
         // Prevent bitcode readers from deleting the debug info.
-        "Debug Info Version".with_c_str(
-            |s| llvm::LLVMRustAddModuleFlag(cx.llmod(), s,
-                                            llvm::LLVMRustDebugMetadataVersion));
+        let ptr = "Debug Info Version\0".as_ptr();
+        llvm::LLVMRustAddModuleFlag(cx.llmod(), ptr as *const _,
+                                    llvm::LLVMRustDebugMetadataVersion);
     };
 }
 
@@ -824,22 +825,20 @@ pub fn create_global_var_metadata(cx: &CrateContext,
         namespace_node.mangled_name_of_contained_item(var_name[]);
     let var_scope = namespace_node.scope;
 
-    var_name.with_c_str(|var_name| {
-        linkage_name.with_c_str(|linkage_name| {
-            unsafe {
-                llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
-                                                        var_scope,
-                                                        var_name,
-                                                        linkage_name,
-                                                        file_metadata,
-                                                        line_number,
-                                                        type_metadata,
-                                                        is_local_to_unit,
-                                                        global,
-                                                        ptr::null_mut());
-            }
-        })
-    });
+    let var_name = CString::from_slice(var_name.as_bytes());
+    let linkage_name = CString::from_slice(linkage_name.as_bytes());
+    unsafe {
+        llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
+                                                var_scope,
+                                                var_name.as_ptr(),
+                                                linkage_name.as_ptr(),
+                                                file_metadata,
+                                                line_number,
+                                                type_metadata,
+                                                is_local_to_unit,
+                                                global,
+                                                ptr::null_mut());
+    }
 }
 
 /// Creates debug information for the given local variable.
@@ -1383,28 +1382,26 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
 
-    let fn_metadata = function_name.with_c_str(|function_name| {
-                          linkage_name.with_c_str(|linkage_name| {
-            unsafe {
-                llvm::LLVMDIBuilderCreateFunction(
-                    DIB(cx),
-                    containing_scope,
-                    function_name,
-                    linkage_name,
-                    file_metadata,
-                    loc.line as c_uint,
-                    function_type_metadata,
-                    is_local_to_unit,
-                    true,
-                    scope_line as c_uint,
-                    FlagPrototyped as c_uint,
-                    cx.sess().opts.optimize != config::No,
-                    llfn,
-                    template_parameters,
-                    ptr::null_mut())
-            }
-        })
-    });
+    let function_name = CString::from_slice(function_name.as_bytes());
+    let linkage_name = CString::from_slice(linkage_name.as_bytes());
+    let fn_metadata = unsafe {
+        llvm::LLVMDIBuilderCreateFunction(
+            DIB(cx),
+            containing_scope,
+            function_name.as_ptr(),
+            linkage_name.as_ptr(),
+            file_metadata,
+            loc.line as c_uint,
+            function_type_metadata,
+            is_local_to_unit,
+            true,
+            scope_line as c_uint,
+            FlagPrototyped as c_uint,
+            cx.sess().opts.optimize != config::No,
+            llfn,
+            template_parameters,
+            ptr::null_mut())
+    };
 
     let scope_map = create_scope_map(cx,
                                      fn_decl.inputs.as_slice(),
@@ -1509,19 +1506,18 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
                 let ident = special_idents::type_self;
 
-                let param_metadata = token::get_ident(ident).get()
-                                                            .with_c_str(|name| {
-                    unsafe {
-                        llvm::LLVMDIBuilderCreateTemplateTypeParameter(
-                            DIB(cx),
-                            file_metadata,
-                            name,
-                            actual_self_type_metadata,
-                            ptr::null_mut(),
-                            0,
-                            0)
-                    }
-                });
+                let ident = token::get_ident(ident);
+                let name = CString::from_slice(ident.get().as_bytes());
+                let param_metadata = unsafe {
+                    llvm::LLVMDIBuilderCreateTemplateTypeParameter(
+                        DIB(cx),
+                        file_metadata,
+                        name.as_ptr(),
+                        actual_self_type_metadata,
+                        ptr::null_mut(),
+                        0,
+                        0)
+                };
 
                 template_params.push(param_metadata);
             }
@@ -1544,19 +1540,18 @@ fn get_template_parameters<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
             // Again, only create type information if full debuginfo is enabled
             if cx.sess().opts.debuginfo == FullDebugInfo {
                 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
-                let param_metadata = token::get_ident(ident).get()
-                                                            .with_c_str(|name| {
-                    unsafe {
-                        llvm::LLVMDIBuilderCreateTemplateTypeParameter(
-                            DIB(cx),
-                            file_metadata,
-                            name,
-                            actual_type_metadata,
-                            ptr::null_mut(),
-                            0,
-                            0)
-                    }
-                });
+                let ident = token::get_ident(ident);
+                let name = CString::from_slice(ident.get().as_bytes());
+                let param_metadata = unsafe {
+                    llvm::LLVMDIBuilderCreateTemplateTypeParameter(
+                        DIB(cx),
+                        file_metadata,
+                        name.as_ptr(),
+                        actual_type_metadata,
+                        ptr::null_mut(),
+                        0,
+                        0)
+                };
                 template_params.push(param_metadata);
             }
         }
@@ -1601,19 +1596,19 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
             } else {
                 match abs_path.path_relative_from(work_dir) {
                     Some(ref p) if p.is_relative() => {
-                            // prepend "./" if necessary
-                            let dotdot = b"..";
-                            let prefix = [dotdot[0], ::std::path::SEP_BYTE];
-                            let mut path_bytes = p.as_vec().to_vec();
-
-                            if path_bytes.slice_to(2) != prefix &&
-                               path_bytes.slice_to(2) != dotdot {
-                                path_bytes.insert(0, prefix[0]);
-                                path_bytes.insert(1, prefix[1]);
-                            }
-
-                            path_bytes.to_c_str()
+                        // prepend "./" if necessary
+                        let dotdot = b"..";
+                        let prefix: &[u8] = &[dotdot[0], ::std::path::SEP_BYTE];
+                        let mut path_bytes = p.as_vec().to_vec();
+
+                        if path_bytes.slice_to(2) != prefix &&
+                           path_bytes.slice_to(2) != dotdot {
+                            path_bytes.insert(0, prefix[0]);
+                            path_bytes.insert(1, prefix[1]);
                         }
+
+                        CString::from_vec(path_bytes)
+                    }
                     _ => fallback_path(cx)
                 }
             }
@@ -1625,29 +1620,25 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor {
                            (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
 
     let compile_unit_name = compile_unit_name.as_ptr();
-    return work_dir.as_vec().with_c_str(|work_dir| {
-        producer.with_c_str(|producer| {
-            "".with_c_str(|flags| {
-                "".with_c_str(|split_name| {
-                    unsafe {
-                        llvm::LLVMDIBuilderCreateCompileUnit(
-                            debug_context(cx).builder,
-                            DW_LANG_RUST,
-                            compile_unit_name,
-                            work_dir,
-                            producer,
-                            cx.sess().opts.optimize != config::No,
-                            flags,
-                            0,
-                            split_name)
-                    }
-                })
-            })
-        })
-    });
+    let work_dir = CString::from_slice(work_dir.as_vec());
+    let producer = CString::from_slice(producer.as_bytes());
+    let flags = "\0";
+    let split_name = "\0";
+    return unsafe {
+        llvm::LLVMDIBuilderCreateCompileUnit(
+            debug_context(cx).builder,
+            DW_LANG_RUST,
+            compile_unit_name,
+            work_dir.as_ptr(),
+            producer.as_ptr(),
+            cx.sess().opts.optimize != config::No,
+            flags.as_ptr() as *const _,
+            0,
+            split_name.as_ptr() as *const _)
+    };
 
     fn fallback_path(cx: &CrateContext) -> CString {
-        cx.link_meta().crate_name.to_c_str()
+        CString::from_slice(cx.link_meta().crate_name.as_bytes())
     }
 }
 
@@ -1673,42 +1664,41 @@ fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         CapturedVariable => (0, DW_TAG_auto_variable)
     };
 
-    let (var_alloca, var_metadata) = name.get().with_c_str(|name| {
-        match variable_access {
-            DirectVariable { alloca } => (
-                alloca,
-                unsafe {
-                    llvm::LLVMDIBuilderCreateLocalVariable(
-                        DIB(cx),
-                        dwarf_tag,
-                        scope_metadata,
-                        name,
-                        file_metadata,
-                        loc.line as c_uint,
-                        type_metadata,
-                        cx.sess().opts.optimize != config::No,
-                        0,
-                        argument_index)
-                }
-            ),
-            IndirectVariable { alloca, address_operations } => (
-                alloca,
-                unsafe {
-                    llvm::LLVMDIBuilderCreateComplexVariable(
-                        DIB(cx),
-                        dwarf_tag,
-                        scope_metadata,
-                        name,
-                        file_metadata,
-                        loc.line as c_uint,
-                        type_metadata,
-                        address_operations.as_ptr(),
-                        address_operations.len() as c_uint,
-                        argument_index)
-                }
-            )
-        }
-    });
+    let name = CString::from_slice(name.get().as_bytes());
+    let (var_alloca, var_metadata) = match variable_access {
+        DirectVariable { alloca } => (
+            alloca,
+            unsafe {
+                llvm::LLVMDIBuilderCreateLocalVariable(
+                    DIB(cx),
+                    dwarf_tag,
+                    scope_metadata,
+                    name.as_ptr(),
+                    file_metadata,
+                    loc.line as c_uint,
+                    type_metadata,
+                    cx.sess().opts.optimize != config::No,
+                    0,
+                    argument_index)
+            }
+        ),
+        IndirectVariable { alloca, address_operations } => (
+            alloca,
+            unsafe {
+                llvm::LLVMDIBuilderCreateComplexVariable(
+                    DIB(cx),
+                    dwarf_tag,
+                    scope_metadata,
+                    name.as_ptr(),
+                    file_metadata,
+                    loc.line as c_uint,
+                    type_metadata,
+                    address_operations.as_ptr(),
+                    address_operations.len() as c_uint,
+                    argument_index)
+            }
+        )
+    };
 
     set_debug_location(cx, DebugLocation::new(scope_metadata,
                                               loc.line,
@@ -1753,14 +1743,12 @@ fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
             full_path
         };
 
-    let file_metadata =
-        file_name.with_c_str(|file_name| {
-            work_dir.with_c_str(|work_dir| {
-                unsafe {
-                    llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
-                }
-            })
-        });
+    let file_name = CString::from_slice(file_name.as_bytes());
+    let work_dir = CString::from_slice(work_dir.as_bytes());
+    let file_metadata = unsafe {
+        llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name.as_ptr(),
+                                      work_dir.as_ptr())
+    };
 
     let mut created_files = debug_context(cx).created_files.borrow_mut();
     created_files.insert(full_path.to_string(), file_metadata);
@@ -1788,16 +1776,14 @@ fn scope_metadata(fcx: &FunctionContext,
 }
 
 fn diverging_type_metadata(cx: &CrateContext) -> DIType {
-    "!".with_c_str(|name| {
-        unsafe {
-            llvm::LLVMDIBuilderCreateBasicType(
-                DIB(cx),
-                name,
-                bytes_to_bits(0),
-                bytes_to_bits(0),
-                DW_ATE_unsigned)
-        }
-    })
+    unsafe {
+        llvm::LLVMDIBuilderCreateBasicType(
+            DIB(cx),
+            "!\0".as_ptr() as *const _,
+            bytes_to_bits(0),
+            bytes_to_bits(0),
+            DW_ATE_unsigned)
+    }
 }
 
 fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
@@ -1833,16 +1819,15 @@ fn basic_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
 
     let llvm_type = type_of::type_of(cx, t);
     let (size, align) = size_and_align_of(cx, llvm_type);
-    let ty_metadata = name.with_c_str(|name| {
-        unsafe {
-            llvm::LLVMDIBuilderCreateBasicType(
-                DIB(cx),
-                name,
-                bytes_to_bits(size),
-                bytes_to_bits(align),
-                encoding)
-        }
-    });
+    let name = CString::from_slice(name.as_bytes());
+    let ty_metadata = unsafe {
+        llvm::LLVMDIBuilderCreateBasicType(
+            DIB(cx),
+            name.as_ptr(),
+            bytes_to_bits(size),
+            bytes_to_bits(align),
+            encoding)
+    };
 
     return ty_metadata;
 }
@@ -1854,16 +1839,15 @@ fn pointer_type_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
     let name = compute_debuginfo_type_name(cx, pointer_type, false);
-    let ptr_metadata = name.with_c_str(|name| {
-        unsafe {
-            llvm::LLVMDIBuilderCreatePointerType(
-                DIB(cx),
-                pointee_type_metadata,
-                bytes_to_bits(pointer_size),
-                bytes_to_bits(pointer_align),
-                name)
-        }
-    });
+    let name = CString::from_slice(name.as_bytes());
+    let ptr_metadata = unsafe {
+        llvm::LLVMDIBuilderCreatePointerType(
+            DIB(cx),
+            pointee_type_metadata,
+            bytes_to_bits(pointer_size),
+            bytes_to_bits(pointer_align),
+            name.as_ptr())
+    };
     return ptr_metadata;
 }
 
@@ -2473,14 +2457,14 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
     let enumerators_metadata: Vec<DIDescriptor> = variants
         .iter()
         .map(|v| {
-            token::get_name(v.name).get().with_c_str(|name| {
-                unsafe {
-                    llvm::LLVMDIBuilderCreateEnumerator(
-                        DIB(cx),
-                        name,
-                        v.disr_val as u64)
-                }
-            })
+            let token = token::get_name(v.name);
+            let name = CString::from_slice(token.get().as_bytes());
+            unsafe {
+                llvm::LLVMDIBuilderCreateEnumerator(
+                    DIB(cx),
+                    name.as_ptr(),
+                    v.disr_val as u64)
+            }
         })
         .collect();
 
@@ -2504,20 +2488,19 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                                   codemap::DUMMY_SP);
                 let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
 
-                let discriminant_type_metadata = discriminant_name.get().with_c_str(|name| {
-                    unsafe {
-                        llvm::LLVMDIBuilderCreateEnumerationType(
-                            DIB(cx),
-                            containing_scope,
-                            name,
-                            UNKNOWN_FILE_METADATA,
-                            UNKNOWN_LINE_NUMBER,
-                            bytes_to_bits(discriminant_size),
-                            bytes_to_bits(discriminant_align),
-                            create_DIArray(DIB(cx), enumerators_metadata[]),
-                            discriminant_base_type_metadata)
-                    }
-                });
+                let name = CString::from_slice(discriminant_name.get().as_bytes());
+                let discriminant_type_metadata = unsafe {
+                    llvm::LLVMDIBuilderCreateEnumerationType(
+                        DIB(cx),
+                        containing_scope,
+                        name.as_ptr(),
+                        UNKNOWN_FILE_METADATA,
+                        UNKNOWN_LINE_NUMBER,
+                        bytes_to_bits(discriminant_size),
+                        bytes_to_bits(discriminant_align),
+                        create_DIArray(DIB(cx), enumerators_metadata.as_slice()),
+                        discriminant_base_type_metadata)
+                };
 
                 debug_context(cx).created_enum_disr_types
                                  .borrow_mut()
@@ -2548,24 +2531,22 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
                              .borrow()
                              .get_unique_type_id_as_string(unique_type_id);
 
-    let enum_metadata = enum_name.with_c_str(|enum_name| {
-        unique_type_id_str.with_c_str(|unique_type_id_str| {
-            unsafe {
-                llvm::LLVMDIBuilderCreateUnionType(
-                DIB(cx),
-                containing_scope,
-                enum_name,
-                UNKNOWN_FILE_METADATA,
-                UNKNOWN_LINE_NUMBER,
-                bytes_to_bits(enum_type_size),
-                bytes_to_bits(enum_type_align),
-                0, // Flags
-                ptr::null_mut(),
-                0, // RuntimeLang
-                unique_type_id_str)
-            }
-        })
-    });
+    let enum_name = CString::from_slice(enum_name.as_bytes());
+    let unique_type_id_str = CString::from_slice(unique_type_id_str.as_bytes());
+    let enum_metadata = unsafe {
+        llvm::LLVMDIBuilderCreateUnionType(
+        DIB(cx),
+        containing_scope,
+        enum_name.as_ptr(),
+        UNKNOWN_FILE_METADATA,
+        UNKNOWN_LINE_NUMBER,
+        bytes_to_bits(enum_type_size),
+        bytes_to_bits(enum_type_align),
+        0, // Flags
+        ptr::null_mut(),
+        0, // RuntimeLang
+        unique_type_id_str.as_ptr())
+    };
 
     return create_and_register_recursive_type_forward_declaration(
         cx,
@@ -2676,21 +2657,20 @@ fn set_members_of_composite_type(cx: &CrateContext,
                 ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
             };
 
-            member_description.name.with_c_str(|member_name| {
-                unsafe {
-                    llvm::LLVMDIBuilderCreateMemberType(
-                        DIB(cx),
-                        composite_type_metadata,
-                        member_name,
-                        UNKNOWN_FILE_METADATA,
-                        UNKNOWN_LINE_NUMBER,
-                        bytes_to_bits(member_size),
-                        bytes_to_bits(member_align),
-                        bytes_to_bits(member_offset),
-                        member_description.flags,
-                        member_description.type_metadata)
-                }
-            })
+            let member_name = CString::from_slice(member_description.name.as_bytes());
+            unsafe {
+                llvm::LLVMDIBuilderCreateMemberType(
+                    DIB(cx),
+                    composite_type_metadata,
+                    member_name.as_ptr(),
+                    UNKNOWN_FILE_METADATA,
+                    UNKNOWN_LINE_NUMBER,
+                    bytes_to_bits(member_size),
+                    bytes_to_bits(member_align),
+                    bytes_to_bits(member_offset),
+                    member_description.flags,
+                    member_description.type_metadata)
+            }
         })
         .collect();
 
@@ -2714,30 +2694,28 @@ fn create_struct_stub(cx: &CrateContext,
     let unique_type_id_str = debug_context(cx).type_map
                                               .borrow()
                                               .get_unique_type_id_as_string(unique_type_id);
+    let name = CString::from_slice(struct_type_name.as_bytes());
+    let unique_type_id = CString::from_slice(unique_type_id_str.as_bytes());
     let metadata_stub = unsafe {
-        struct_type_name.with_c_str(|name| {
-            unique_type_id_str.with_c_str(|unique_type_id| {
-                // LLVMDIBuilderCreateStructType() wants an empty array. A null
-                // pointer will lead to hard to trace and debug LLVM assertions
-                // later on in llvm/lib/IR/Value.cpp.
-                let empty_array = create_DIArray(DIB(cx), &[]);
-
-                llvm::LLVMDIBuilderCreateStructType(
-                    DIB(cx),
-                    containing_scope,
-                    name,
-                    UNKNOWN_FILE_METADATA,
-                    UNKNOWN_LINE_NUMBER,
-                    bytes_to_bits(struct_size),
-                    bytes_to_bits(struct_align),
-                    0,
-                    ptr::null_mut(),
-                    empty_array,
-                    0,
-                    ptr::null_mut(),
-                    unique_type_id)
-            })
-        })
+        // LLVMDIBuilderCreateStructType() wants an empty array. A null
+        // pointer will lead to hard to trace and debug LLVM assertions
+        // later on in llvm/lib/IR/Value.cpp.
+        let empty_array = create_DIArray(DIB(cx), &[]);
+
+        llvm::LLVMDIBuilderCreateStructType(
+            DIB(cx),
+            containing_scope,
+            name.as_ptr(),
+            UNKNOWN_FILE_METADATA,
+            UNKNOWN_LINE_NUMBER,
+            bytes_to_bits(struct_size),
+            bytes_to_bits(struct_align),
+            0,
+            ptr::null_mut(),
+            empty_array,
+            0,
+            ptr::null_mut(),
+            unique_type_id.as_ptr())
     };
 
     return metadata_stub;
@@ -3464,7 +3442,7 @@ fn walk_pattern(cx: &CrateContext,
                 }
             }
 
-            ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat) => {
+            ast::PatBox(ref sub_pat) | ast::PatRegion(ref sub_pat, _) => {
                 scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
                 walk_pattern(cx, &**sub_pat, scope_stack, scope_map);
             }
@@ -4011,18 +3989,18 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
                         None => ptr::null_mut()
                     };
                     let namespace_name = token::get_name(name);
-                    let scope = namespace_name.get().with_c_str(|namespace_name| {
-                        unsafe {
-                            llvm::LLVMDIBuilderCreateNameSpace(
-                                DIB(cx),
-                                parent_scope,
-                                namespace_name,
-                                // cannot reconstruct file ...
-                                ptr::null_mut(),
-                                // ... or line information, but that's not so important.
-                                0)
-                        }
-                    });
+                    let namespace_name = CString::from_slice(namespace_name
+                                                                .get().as_bytes());
+                    let scope = unsafe {
+                        llvm::LLVMDIBuilderCreateNameSpace(
+                            DIB(cx),
+                            parent_scope,
+                            namespace_name.as_ptr(),
+                            // cannot reconstruct file ...
+                            ptr::null_mut(),
+                            // ... or line information, but that's not so important.
+                            0)
+                    };
 
                     let node = Rc::new(NamespaceTreeNode {
                         name: name,
@@ -4060,7 +4038,7 @@ fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTree
 /// .debug_gdb_scripts global is referenced, so it isn't removed by the linker.
 pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext) {
     if needs_gdb_debug_scripts_section(ccx) {
-        let empty = b"".to_c_str();
+        let empty = CString::from_slice(b"");
         let gdb_debug_scripts_section_global =
             get_or_insert_gdb_debug_scripts_section_global(ccx);
         unsafe {
@@ -4077,14 +4055,15 @@ pub fn insert_reference_to_gdb_debug_scripts_section_global(ccx: &CrateContext)
 /// section.
 fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext)
                                                   -> llvm::ValueRef {
-    let section_var_name = b"__rustc_debug_gdb_scripts_section__".to_c_str();
+    let section_var_name = b"__rustc_debug_gdb_scripts_section__\0";
 
     let section_var = unsafe {
-        llvm::LLVMGetNamedGlobal(ccx.llmod(), section_var_name.as_ptr())
+        llvm::LLVMGetNamedGlobal(ccx.llmod(),
+                                 section_var_name.as_ptr() as *const _)
     };
 
     if section_var == ptr::null_mut() {
-        let section_name = b".debug_gdb_scripts".to_c_str();
+        let section_name = b".debug_gdb_scripts\0";
         let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
 
         unsafe {
@@ -4092,8 +4071,9 @@ fn get_or_insert_gdb_debug_scripts_section_global(ccx: &CrateContext)
                                         section_contents.len() as u64);
             let section_var = llvm::LLVMAddGlobal(ccx.llmod(),
                                                   llvm_type.to_ref(),
-                                                  section_var_name.as_ptr());
-            llvm::LLVMSetSection(section_var, section_name.as_ptr());
+                                                  section_var_name.as_ptr()
+                                                    as *const _);
+            llvm::LLVMSetSection(section_var, section_name.as_ptr() as *const _);
             llvm::LLVMSetInitializer(section_var, C_bytes(ccx, section_contents));
             llvm::LLVMSetGlobalConstant(section_var, llvm::True);
             llvm::LLVMSetUnnamedAddr(section_var, llvm::True);
index a4cfec791d8172e5fa32385e83eac4fa7f98cdd3..1c9be6ae4a8ba5e357566cf1ff2d65834ac56020 100644 (file)
 use trans::type_of::*;
 use trans::type_of;
 use middle::ty::{self, Ty};
-use middle::subst::{Substs};
+use middle::subst::Substs;
+
+use std::ffi::CString;
 use std::cmp;
-use std::c_str::ToCStr;
 use libc::c_uint;
 use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi};
 use syntax::abi::{RustIntrinsic, Rust, RustCall, Stdcall, Fastcall, System};
@@ -132,9 +133,9 @@ pub fn register_static(ccx: &CrateContext,
             };
             unsafe {
                 // Declare a symbol `foo` with the desired linkage.
-                let g1 = ident.get().with_c_str(|buf| {
-                    llvm::LLVMAddGlobal(ccx.llmod(), llty2.to_ref(), buf)
-                });
+                let buf = CString::from_slice(ident.get().as_bytes());
+                let g1 = llvm::LLVMAddGlobal(ccx.llmod(), llty2.to_ref(),
+                                             buf.as_ptr());
                 llvm::SetLinkage(g1, linkage);
 
                 // Declare an internal global `extern_with_linkage_foo` which
@@ -145,9 +146,9 @@ pub fn register_static(ccx: &CrateContext,
                 // zero.
                 let mut real_name = "_rust_extern_with_linkage_".to_string();
                 real_name.push_str(ident.get());
-                let g2 = real_name.with_c_str(|buf| {
-                    llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), buf)
-                });
+                let real_name = CString::from_vec(real_name.into_bytes());
+                let g2 = llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(),
+                                             real_name.as_ptr());
                 llvm::SetLinkage(g2, llvm::InternalLinkage);
                 llvm::LLVMSetInitializer(g2, g1);
                 g2
@@ -155,9 +156,8 @@ pub fn register_static(ccx: &CrateContext,
         }
         None => unsafe {
             // Generate an external declaration.
-            ident.get().with_c_str(|buf| {
-                llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), buf)
-            })
+            let buf = CString::from_slice(ident.get().as_bytes());
+            llvm::LLVMAddGlobal(ccx.llmod(), llty.to_ref(), buf.as_ptr())
         }
     }
 }
@@ -606,9 +606,9 @@ unsafe fn build_wrap_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         //         return r;
         //     }
 
-        let the_block =
-            "the block".with_c_str(
-                |s| llvm::LLVMAppendBasicBlockInContext(ccx.llcx(), llwrapfn, s));
+        let ptr = "the block\0".as_ptr();
+        let the_block = llvm::LLVMAppendBasicBlockInContext(ccx.llcx(), llwrapfn,
+                                                            ptr as *const _);
 
         let builder = ccx.builder();
         builder.position_at_end(the_block);
index 491c6a83ca9bf39fb4296f907fdb4838fac8ead0..2fd9031fdfe4cc7f6e74fc1d70c40da040c26ad0 100644 (file)
@@ -40,8 +40,8 @@
 use util::ppaux;
 
 use arena::TypedArena;
-use std::c_str::ToCStr;
 use libc::c_uint;
+use std::ffi::CString;
 use syntax::ast;
 use syntax::parse::token;
 
@@ -486,11 +486,11 @@ pub fn declare_tydesc<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>)
     let llalign = llalign_of(ccx, llty);
     let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc");
     debug!("+++ declare_tydesc {} {}", ppaux::ty_to_string(ccx.tcx(), t), name);
-    let gvar = name.with_c_str(|buf| {
-        unsafe {
-            llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(), buf)
-        }
-    });
+    let buf = CString::from_slice(name.as_bytes());
+    let gvar = unsafe {
+        llvm::LLVMAddGlobal(ccx.llmod(), ccx.tydesc_type().to_ref(),
+                            buf.as_ptr())
+    };
     note_unique_llvm_symbol(ccx, name);
 
     let ty_name = token::intern_and_get_ident(
index dcf3a53215788784c38a317bb0a7ae4de30daf9d..de0f714276d0de4ec94a6513de0161193b24d001 100644 (file)
@@ -12,7 +12,7 @@
 use trans::type_::Type;
 use llvm::ValueRef;
 
-pub trait LlvmRepr for Sized? {
+pub trait LlvmRepr {
     fn llrepr(&self, ccx: &CrateContext) -> String;
 }
 
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 e219b45d3d9f499ee07eb36d97fc97b0a27e565a..f6d69959dadf9ecec5607e0b0a17cdb6f03a7240 100644 (file)
@@ -34,7 +34,7 @@
 use middle::ty::MethodCall;
 use util::ppaux::Repr;
 
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::rc::Rc;
 use syntax::abi::{Rust, RustCall};
 use syntax::parse::token;
@@ -762,9 +762,9 @@ pub fn make_vtable<I: Iterator<Item=ValueRef>>(ccx: &CrateContext,
     unsafe {
         let tbl = C_struct(ccx, components[], false);
         let sym = token::gensym("vtable");
-        let vt_gvar = format!("vtable{}", sym.uint()).with_c_str(|buf| {
-            llvm::LLVMAddGlobal(ccx.llmod(), val_ty(tbl).to_ref(), buf)
-        });
+        let buf = CString::from_vec(format!("vtable{}", sym.uint()).into_bytes());
+        let vt_gvar = llvm::LLVMAddGlobal(ccx.llmod(), val_ty(tbl).to_ref(),
+                                          buf.as_ptr());
         llvm::LLVMSetInitializer(vt_gvar, tbl);
         llvm::LLVMSetGlobalConstant(vt_gvar, llvm::True);
         llvm::SetLinkage(vt_gvar, llvm::InternalLinkage);
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 5b76f5bb8270e77b12f76f81cf664a3cb8aec423..3785c2fb9bc54e5b633e3dd36099266ed2840dec 100644 (file)
@@ -19,7 +19,7 @@
 
 use syntax::ast;
 
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::mem;
 use std::cell::RefCell;
 use std::iter::repeat;
@@ -157,7 +157,8 @@ pub fn struct_(ccx: &CrateContext, els: &[Type], packed: bool) -> Type {
     }
 
     pub fn named_struct(ccx: &CrateContext, name: &str) -> Type {
-        ty!(name.with_c_str(|s| llvm::LLVMStructCreateNamed(ccx.llcx(), s)))
+        let name = CString::from_slice(name.as_bytes());
+        ty!(llvm::LLVMStructCreateNamed(ccx.llcx(), name.as_ptr()))
     }
 
     pub fn empty_struct(ccx: &CrateContext) -> Type {
index bde834c2ff899d4c4cf15f2f473049e11fc4faac..183b8c5c830ef0f29f71ab43c683120f755190cb 100644 (file)
@@ -361,14 +361,6 @@ fn create_substs_for_ast_path<'tcx>(
                                            supplied_ty_param_count)[]);
     }
 
-    if supplied_ty_param_count > required_ty_param_count
-        && !this.tcx().sess.features.borrow().default_type_params {
-        span_err!(this.tcx().sess, span, E0108,
-            "default type parameters are experimental and possibly buggy");
-        span_help!(this.tcx().sess, span,
-            "add #![feature(default_type_params)] to the crate attributes to enable");
-    }
-
     let mut substs = Substs::new_type(types, regions);
 
     match self_ty {
index 56cf4acc184e5dd7613902188aefdc1cf694289c..80e7e7060595675b2e09485b529fb4dcb0981f4d 100644 (file)
@@ -30,7 +30,9 @@
 use syntax::ptr::P;
 
 pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
-                           pat: &ast::Pat, expected: Ty<'tcx>) {
+                           pat: &ast::Pat,
+                           expected: Ty<'tcx>)
+{
     let fcx = pcx.fcx;
     let tcx = pcx.fcx.ccx.tcx;
 
@@ -46,6 +48,19 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             check_expr(fcx, &**lt);
             let expr_ty = fcx.expr_ty(&**lt);
             fcx.write_ty(pat.id, expr_ty);
+
+            // somewhat surprising: in this case, the subtyping
+            // relation goes the opposite way as the other
+            // cases. Actually what we really want is not a subtyping
+            // relation at all but rather that there exists a LUB (so
+            // that they can be compared). However, in practice,
+            // constants are always scalars or strings.  For scalars
+            // subtyping is irrelevant, and for strings `expr_ty` is
+            // type is `&'static str`, so if we say that
+            //
+            //     &'static str <: expected
+            //
+            // that's equivalent to there existing a LUB.
             demand::suptype(fcx, pat.span, expected, expr_ty);
         }
         ast::PatRange(ref begin, ref end) => {
@@ -54,10 +69,16 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
 
             let lhs_ty = fcx.expr_ty(&**begin);
             let rhs_ty = fcx.expr_ty(&**end);
-            if require_same_types(
-                tcx, Some(fcx.infcx()), false, pat.span, lhs_ty, rhs_ty,
-                || "mismatched types in range".to_string())
-                && (ty::type_is_numeric(lhs_ty) || ty::type_is_char(rhs_ty)) {
+
+            let lhs_eq_rhs =
+                require_same_types(
+                    tcx, Some(fcx.infcx()), false, pat.span, lhs_ty, rhs_ty,
+                    || "mismatched types in range".to_string());
+
+            let numeric_or_char =
+                lhs_eq_rhs && (ty::type_is_numeric(lhs_ty) || ty::type_is_char(lhs_ty));
+
+            if numeric_or_char {
                 match valid_range_bounds(fcx.ccx, &**begin, &**end) {
                     Some(false) => {
                         span_err!(tcx.sess, begin.span, E0030,
@@ -71,17 +92,29 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                 }
             } else {
                 span_err!(tcx.sess, begin.span, E0029,
-                    "only char and numeric types are allowed in range");
+                          "only char and numeric types are allowed in range");
             }
 
             fcx.write_ty(pat.id, lhs_ty);
+
+            // subtyping doens't matter here, as the value is some kind of scalar
             demand::eqtype(fcx, pat.span, expected, lhs_ty);
         }
         ast::PatEnum(..) | ast::PatIdent(..) if pat_is_const(&tcx.def_map, pat) => {
             let const_did = tcx.def_map.borrow()[pat.id].clone().def_id();
             let const_scheme = ty::lookup_item_type(tcx, const_did);
-            fcx.write_ty(pat.id, const_scheme.ty);
-            demand::suptype(fcx, pat.span, expected, const_scheme.ty);
+            assert!(const_scheme.generics.is_empty());
+            let const_ty = pcx.fcx.instantiate_type_scheme(pat.span,
+                                                           &Substs::empty(),
+                                                           &const_scheme.ty);
+            fcx.write_ty(pat.id, const_ty);
+
+            // FIXME(#20489) -- we should limit the types here to scalars or something!
+
+            // As with PatLit, what we really want here is that there
+            // exist a LUB, but for the cases that can occur, subtype
+            // is good enough.
+            demand::suptype(fcx, pat.span, expected, const_ty);
         }
         ast::PatIdent(bm, ref path, ref sub) if pat_is_binding(&tcx.def_map, pat) => {
             let typ = fcx.local_ty(pat.span, pat.id);
@@ -89,20 +122,29 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                 ast::BindByRef(mutbl) => {
                     // if the binding is like
                     //    ref x | ref const x | ref mut x
-                    // then the type of x is &M T where M is the mutability
-                    // and T is the expected type
+                    // then `x` is assigned a value of type `&M T` where M is the mutability
+                    // and T is the expected type.
                     let region_var = fcx.infcx().next_region_var(infer::PatternRegion(pat.span));
                     let mt = ty::mt { ty: expected, mutbl: mutbl };
                     let region_ty = ty::mk_rptr(tcx, tcx.mk_region(region_var), mt);
+
+                    // `x` is assigned a value of type `&M T`, hence `&M T <: typeof(x)` is
+                    // required. However, we use equality, which is stronger. See (*) for
+                    // an explanation.
                     demand::eqtype(fcx, pat.span, region_ty, typ);
                 }
                 // otherwise the type of x is the expected type T
                 ast::BindByValue(_) => {
+                    // As above, `T <: typeof(x)` is required but we
+                    // use equality, see (*) below.
                     demand::eqtype(fcx, pat.span, expected, typ);
                 }
             }
+
             fcx.write_ty(pat.id, typ);
 
+            // if there are multiple arms, make sure they all agree on
+            // what the type of the binding `x` ought to be
             let canon_id = pcx.map[path.node];
             if canon_id != pat.id {
                 let ct = fcx.local_ty(pat.span, canon_id);
@@ -124,8 +166,9 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             check_pat_struct(pcx, pat, path, fields.as_slice(), etc, expected);
         }
         ast::PatTup(ref elements) => {
-            let element_tys: Vec<_> = range(0, elements.len()).map(|_| fcx.infcx()
-                .next_ty_var()).collect();
+            let element_tys: Vec<_> =
+                range(0, elements.len()).map(|_| fcx.infcx().next_ty_var())
+                                        .collect();
             let pat_ty = ty::mk_tup(tcx, element_tys.clone());
             fcx.write_ty(pat.id, pat_ty);
             demand::eqtype(fcx, pat.span, expected, pat_ty);
@@ -138,7 +181,10 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
             let uniq_ty = ty::mk_uniq(tcx, inner_ty);
 
             if check_dereferencable(pcx, pat.span, expected, &**inner) {
-                demand::suptype(fcx, pat.span, expected, uniq_ty);
+                // Here, `demand::subtype` is good enough, but I don't
+                // think any errors can be introduced by using
+                // `demand::eqtype`.
+                demand::eqtype(fcx, pat.span, expected, uniq_ty);
                 fcx.write_ty(pat.id, uniq_ty);
                 check_pat(pcx, &**inner, inner_ty);
             } else {
@@ -146,19 +192,26 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                 check_pat(pcx, &**inner, tcx.types.err);
             }
         }
-        ast::PatRegion(ref inner) => {
+        ast::PatRegion(ref inner, mutbl) => {
             let inner_ty = fcx.infcx().next_ty_var();
 
-            let mutbl =
+            // SNAP b2085d9 remove this `if`-`else` entirely after next snapshot
+            let mutbl = if mutbl == ast::MutImmutable {
                 ty::deref(fcx.infcx().shallow_resolve(expected), true)
-                .map_or(ast::MutImmutable, |mt| mt.mutbl);
+                   .map(|mt| mt.mutbl).unwrap_or(ast::MutImmutable)
+            } else {
+                mutbl
+            };
 
             let mt = ty::mt { ty: inner_ty, mutbl: mutbl };
             let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span));
             let rptr_ty = ty::mk_rptr(tcx, tcx.mk_region(region), mt);
 
             if check_dereferencable(pcx, pat.span, expected, &**inner) {
-                demand::suptype(fcx, pat.span, expected, rptr_ty);
+                // `demand::subtype` would be good enough, but using
+                // `eqtype` turns out to be equally general. See (*)
+                // below for details.
+                demand::eqtype(fcx, pat.span, expected, rptr_ty);
                 fcx.write_ty(pat.id, rptr_ty);
                 check_pat(pcx, &**inner, inner_ty);
             } else {
@@ -181,14 +234,18 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
                     let region = fcx.infcx().next_region_var(infer::PatternRegion(pat.span));
                     ty::mk_slice(tcx, tcx.mk_region(region), ty::mt {
                         ty: inner_ty,
-                        mutbl: ty::deref(expected_ty, true)
-                            .map_or(ast::MutImmutable, |mt| mt.mutbl)
+                        mutbl: ty::deref(expected_ty, true).map(|mt| mt.mutbl)
+                                                           .unwrap_or(ast::MutImmutable)
                     })
                 }
             };
 
             fcx.write_ty(pat.id, pat_ty);
-            demand::suptype(fcx, pat.span, expected, pat_ty);
+
+            // `demand::subtype` would be good enough, but using
+            // `eqtype` turns out to be equally general. See (*)
+            // below for details.
+            demand::eqtype(fcx, pat.span, expected, pat_ty);
 
             for elt in before.iter() {
                 check_pat(pcx, &**elt, inner_ty);
@@ -210,6 +267,56 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         }
         ast::PatMac(_) => tcx.sess.bug("unexpanded macro")
     }
+
+
+    // (*) In most of the cases above (literals and constants being
+    // the exception), we relate types using strict equality, evewn
+    // though subtyping would be sufficient. There are a few reasons
+    // for this, some of which are fairly subtle and which cost me
+    // (nmatsakis) an hour or two debugging to remember, so I thought
+    // I'd write them down this time.
+    //
+    // 1. Most importantly, there is no loss of expressiveness
+    // here. What we are saying is that the type of `x`
+    // becomes *exactly* what is expected. This might seem
+    // like it will cause errors in a case like this:
+    //
+    // ```
+    // fn foo<'x>(x: &'x int) {
+    //    let a = 1;
+    //    let mut z = x;
+    //    z = &a;
+    // }
+    // ```
+    //
+    // The reason we might get an error is that `z` might be
+    // assigned a type like `&'x int`, and then we would have
+    // a problem when we try to assign `&a` to `z`, because
+    // the lifetime of `&a` (i.e., the enclosing block) is
+    // shorter than `'x`.
+    //
+    // HOWEVER, this code works fine. The reason is that the
+    // expected type here is whatever type the user wrote, not
+    // the initializer's type. In this case the user wrote
+    // nothing, so we are going to create a type variable `Z`.
+    // Then we will assign the type of the initializer (`&'x
+    // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we
+    // will instantiate `Z` as a type `&'0 int` where `'0` is
+    // a fresh region variable, with the constraint that `'x :
+    // '0`.  So basically we're all set.
+    //
+    // Note that there are two tests to check that this remains true
+    // (`regions-reassign-{match,let}-bound-pointer.rs`).
+    //
+    // 2. Things go horribly wrong if we use subtype. The reason for
+    // THIS is a fairly subtle case involving bound regions. See the
+    // `givens` field in `region_inference`, as well as the test
+    // `regions-relate-bound-regions-on-closures-to-inference-variables.rs`,
+    // for details. Short version is that we must sometimes detect
+    // relationships between specific region variables and regions
+    // bound in a closure signature, and that detection gets thrown
+    // off when we substitute fresh region variables here to enable
+    // subtyping.
 }
 
 pub fn check_dereferencable<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
index 98a826355a73ac8e78719c637f9853b7e9674703..b1dc033b567bbf659f58053bb30d68b553c33efe 100644 (file)
@@ -22,7 +22,7 @@
 use super::write_call;
 
 use middle::infer;
-use middle::ty::{mod, Ty};
+use middle::ty::{self, Ty};
 use syntax::ast;
 use syntax::codemap::Span;
 use syntax::parse::token;
index 5b586bb0b669a2503468444881436e886b75605c..a51e89c1669de7cd6d4fa0d8972ab5f17c68c528 100644 (file)
 use syntax::codemap::Span;
 use util::ppaux::Repr;
 
-// Requires that the two types unify, and prints an error message if they
-// don't.
+// Requires that the two types unify, and prints an error message if
+// they don't.
 pub fn suptype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
-                         expected: Ty<'tcx>, actual: Ty<'tcx>) {
-    suptype_with_fn(fcx, sp, false, expected, actual,
+                         ty_expected: Ty<'tcx>, ty_actual: Ty<'tcx>) {
+    suptype_with_fn(fcx, sp, false, ty_expected, ty_actual,
         |sp, e, a, s| { fcx.report_mismatched_types(sp, e, a, s) })
 }
 
+/// As `suptype`, but call `handle_err` if unification for subtyping fails.
 pub fn suptype_with_fn<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                                     sp: Span,
                                     b_is_expected: bool,
@@ -48,9 +49,7 @@ pub fn eqtype<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, sp: Span,
                         expected: Ty<'tcx>, actual: Ty<'tcx>) {
     match infer::mk_eqty(fcx.infcx(), false, infer::Misc(sp), actual, expected) {
         Ok(()) => { /* ok */ }
-        Err(ref err) => {
-            fcx.report_mismatched_types(sp, expected, actual, err);
-        }
+        Err(ref err) => { fcx.report_mismatched_types(sp, expected, actual, err); }
     }
 }
 
index beb51590b4159249338029abcf52a678e6149b2f..115711ae92b297f75360699e7c29198173370d81 100644 (file)
@@ -442,7 +442,7 @@ fn assemble_extension_candidates_for_traits_in_scope(&mut self,
 
     fn assemble_extension_candidates_for_trait(&mut self,
                                                trait_def_id: ast::DefId) {
-        debug!("assemble_extension_candidates_for_trait: trait_def_id={}",
+        debug!("assemble_extension_candidates_for_trait(trait_def_id={})",
                trait_def_id.repr(self.tcx()));
 
         // Check whether `trait_def_id` defines a method with suitable name:
@@ -471,8 +471,12 @@ fn assemble_extension_candidates_for_trait(&mut self,
                                                            matching_index);
 
         self.assemble_unboxed_closure_candidates(trait_def_id,
-                                                 method,
+                                                 method.clone(),
                                                  matching_index);
+
+        self.assemble_where_clause_candidates(trait_def_id,
+                                              method,
+                                              matching_index);
     }
 
     fn assemble_extension_candidates_for_trait_impls(&mut self,
@@ -599,6 +603,35 @@ fn assemble_unboxed_closure_candidates(&mut self,
         }
     }
 
+    fn assemble_where_clause_candidates(&mut self,
+                                        trait_def_id: ast::DefId,
+                                        method_ty: Rc<ty::Method<'tcx>>,
+                                        method_index: uint)
+    {
+        debug!("assemble_where_clause_candidates(trait_def_id={})",
+               trait_def_id.repr(self.tcx()));
+
+        // Check whether there are any where-clauses pertaining to this trait.
+        let caller_predicates =
+            self.fcx.inh.param_env.caller_bounds.predicates.as_slice().to_vec();
+        for bound in traits::elaborate_predicates(self.tcx(), caller_predicates)
+                     .filter_map(|p| p.to_opt_poly_trait_ref())
+                     .filter(|b| b.def_id() == trait_def_id)
+        {
+            let xform_self_ty = self.xform_self_ty(&method_ty, bound.substs());
+
+            debug!("assemble_where_clause_candidates: bound={} xform_self_ty={}",
+                   bound.repr(self.tcx()),
+                   xform_self_ty.repr(self.tcx()));
+
+            self.extension_candidates.push(Candidate {
+                xform_self_ty: xform_self_ty,
+                method_ty: method_ty.clone(),
+                kind: WhereClauseCandidate(bound, method_index)
+            });
+        }
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // THE ACTUAL SEARCH
 
@@ -774,26 +807,26 @@ fn consider_probe(&self, self_ty: Ty<'tcx>, probe: &Candidate<'tcx>) -> bool {
             match probe.kind {
                 InherentImplCandidate(impl_def_id, ref substs) |
                 ExtensionImplCandidate(impl_def_id, _, ref substs, _) => {
+                    let selcx = &mut traits::SelectionContext::new(self.infcx(), self.fcx);
+                    let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
+
                     // Check whether the impl imposes obligations we have to worry about.
                     let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
                     let impl_bounds = impl_generics.to_bounds(self.tcx(), substs);
-                    // FIXME(#20378) assoc type normalization here?
-
-                    // Erase any late-bound regions bound in the impl
-                    // which appear in the bounds.
-                    let impl_bounds = self.erase_late_bound_regions(&ty::Binder(impl_bounds));
+                    let traits::Normalized { value: impl_bounds,
+                                             obligations: norm_obligations } =
+                        traits::normalize(selcx, cause.clone(), &impl_bounds);
 
                     // Convert the bounds into obligations.
                     let obligations =
-                        traits::predicates_for_generics(
-                            self.tcx(),
-                            traits::ObligationCause::misc(self.span, self.fcx.body_id),
-                            &impl_bounds);
+                        traits::predicates_for_generics(self.tcx(),
+                                                        cause.clone(),
+                                                        &impl_bounds);
                     debug!("impl_obligations={}", obligations.repr(self.tcx()));
 
                     // Evaluate those obligations to see if they might possibly hold.
-                    let mut selcx = traits::SelectionContext::new(self.infcx(), self.fcx);
-                    obligations.all(|o| selcx.evaluate_obligation(o))
+                    obligations.all(|o| selcx.evaluate_obligation(o)) &&
+                        norm_obligations.iter().all(|o| selcx.evaluate_obligation(o))
                 }
 
                 ObjectCandidate(..) |
index 2940d556169686ddde78225def60113568f3fd54..1b51434a58cc130c5f20b9a73810ee4ba797b0c9 100644 (file)
@@ -4554,7 +4554,7 @@ fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
 pub fn check_decl_initializer(fcx: &FnCtxt,
                               nid: ast::NodeId,
                               init: &ast::Expr)
-                            {
+{
     let local_ty = fcx.local_ty(init.span, nid);
     check_expr_coercable_to_type(fcx, init, local_ty)
 }
index 5a8263263808ee1eab07c18217294bfbac925867..c7df5ed8453fd3a990658694248c632f5f65dfef 100644 (file)
@@ -92,7 +92,7 @@
 use middle::traits;
 use middle::ty::{ReScope};
 use middle::ty::{self, Ty, MethodCall};
-use middle::infer;
+use middle::infer::{self, GenericKind};
 use middle::pat_util;
 use util::ppaux::{ty_to_string, Repr};
 
@@ -164,7 +164,7 @@ pub fn regionck_ensure_component_tys_wf<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 pub struct Rcx<'a, 'tcx: 'a> {
     fcx: &'a FnCtxt<'a, 'tcx>,
 
-    region_param_pairs: Vec<(ty::Region, ty::ParamTy)>,
+    region_bound_pairs: Vec<(ty::Region, GenericKind<'tcx>)>,
 
     // id of innermost fn or loop
     repeating_scope: ast::NodeId,
@@ -205,7 +205,7 @@ pub fn new(fcx: &'a FnCtxt<'a, 'tcx>,
         Rcx { fcx: fcx,
               repeating_scope: initial_repeating_scope,
               subject: subject,
-              region_param_pairs: Vec::new() }
+              region_bound_pairs: Vec::new() }
     }
 
     pub fn tcx(&self) -> &'a ty::ctxt<'tcx> {
@@ -286,12 +286,12 @@ fn visit_fn_body(&mut self,
             }
         };
 
-        let len = self.region_param_pairs.len();
+        let len = self.region_bound_pairs.len();
         self.relate_free_regions(fn_sig[], body.id);
         link_fn_args(self, CodeExtent::from_node_id(body.id), fn_decl.inputs[]);
         self.visit_block(body);
         self.visit_region_obligations(body.id);
-        self.region_param_pairs.truncate(len);
+        self.region_bound_pairs.truncate(len);
     }
 
     fn visit_region_obligations(&mut self, node_id: ast::NodeId)
@@ -357,11 +357,11 @@ fn relate_free_regions(&mut self,
                         // relationship that arises here, but
                         // presently we do not.)
                     }
-                    regionmanip::RegionSubParamConstraint(_, r_a, p_b) => {
-                        debug!("RegionSubParamConstraint: {} <= {}",
-                               r_a.repr(tcx), p_b.repr(tcx));
+                    regionmanip::RegionSubGenericConstraint(_, r_a, ref generic_b) => {
+                        debug!("RegionSubGenericConstraint: {} <= {}",
+                               r_a.repr(tcx), generic_b.repr(tcx));
 
-                        self.region_param_pairs.push((r_a, p_b));
+                        self.region_bound_pairs.push((r_a, generic_b.clone()));
                     }
                 }
             }
@@ -1427,31 +1427,31 @@ fn type_must_outlive<'a, 'tcx>(rcx: &mut Rcx<'a, 'tcx>,
                 let o1 = infer::ReferenceOutlivesReferent(ty, origin.span());
                 rcx.fcx.mk_subr(o1, r_a, r_b);
             }
-            regionmanip::RegionSubParamConstraint(None, r_a, param_b) => {
-                param_must_outlive(rcx, origin.clone(), r_a, param_b);
+            regionmanip::RegionSubGenericConstraint(None, r_a, ref generic_b) => {
+                generic_must_outlive(rcx, origin.clone(), r_a, generic_b);
             }
-            regionmanip::RegionSubParamConstraint(Some(ty), r_a, param_b) => {
+            regionmanip::RegionSubGenericConstraint(Some(ty), r_a, ref generic_b) => {
                 let o1 = infer::ReferenceOutlivesReferent(ty, origin.span());
-                param_must_outlive(rcx, o1, r_a, param_b);
+                generic_must_outlive(rcx, o1, r_a, generic_b);
             }
         }
     }
 }
 
-fn param_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
-                                origin: infer::SubregionOrigin<'tcx>,
-                                region: ty::Region,
-                                param_ty: ty::ParamTy) {
+fn generic_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
+                                  origin: infer::SubregionOrigin<'tcx>,
+                                  region: ty::Region,
+                                  generic: &GenericKind<'tcx>) {
     let param_env = &rcx.fcx.inh.param_env;
 
-    debug!("param_must_outlive(region={}, param_ty={})",
+    debug!("param_must_outlive(region={}, generic={})",
            region.repr(rcx.tcx()),
-           param_ty.repr(rcx.tcx()));
+           generic.repr(rcx.tcx()));
 
     // To start, collect bounds from user:
     let mut param_bounds =
         ty::required_region_bounds(rcx.tcx(),
-                                   param_ty.to_ty(rcx.tcx()),
+                                   generic.to_ty(rcx.tcx()),
                                    param_env.caller_bounds.predicates.as_slice().to_vec());
 
     // Add in the default bound of fn body that applies to all in
@@ -1467,22 +1467,21 @@ fn param_must_outlive<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>,
     //     fn foo<'a, A>(x: &'a A) { x.bar() }
     //
     // The problem is that the type of `x` is `&'a A`. To be
-    // well-formed, then, A must be lower-bounded by `'a`, but we
+    // well-formed, then, A must be lower-generic by `'a`, but we
     // don't know that this holds from first principles.
-    for &(ref r, ref p) in rcx.region_param_pairs.iter() {
-        debug!("param_ty={} p={}",
-               param_ty.repr(rcx.tcx()),
+    for &(ref r, ref p) in rcx.region_bound_pairs.iter() {
+        debug!("generic={} p={}",
+               generic.repr(rcx.tcx()),
                p.repr(rcx.tcx()));
-        if param_ty == *p {
+        if generic == p {
             param_bounds.push(*r);
         }
     }
 
-    // Inform region inference that this parameter type must be
-    // properly bounded.
-    infer::verify_param_bound(rcx.fcx.infcx(),
-                              origin,
-                              param_ty,
-                              region,
-                              param_bounds);
+    // Inform region inference that this generic must be properly
+    // bounded.
+    rcx.fcx.infcx().verify_generic_bound(origin,
+                                         generic.clone(),
+                                         region,
+                                         param_bounds);
 }
index 7a9961e750c217fb30deed5c03beea4257fa5263..7ca21bdf5b83f7eaacac5c1114a9107cb9e25801 100644 (file)
@@ -12,6 +12,7 @@
 
 pub use self::WfConstraint::*;
 
+use middle::infer::GenericKind;
 use middle::subst::{ParamSpace, Subst, Substs};
 use middle::ty::{self, Ty};
 use middle::ty_fold::{TypeFolder};
@@ -24,7 +25,7 @@
 
 pub enum WfConstraint<'tcx> {
     RegionSubRegionConstraint(Option<Ty<'tcx>>, ty::Region, ty::Region),
-    RegionSubParamConstraint(Option<Ty<'tcx>>, ty::Region, ty::ParamTy),
+    RegionSubGenericConstraint(Option<Ty<'tcx>>, ty::Region, GenericKind<'tcx>),
 }
 
 struct Wf<'a, 'tcx: 'a> {
@@ -121,8 +122,7 @@ fn accumulate_from_ty(&mut self, ty: Ty<'tcx>) {
             ty::ty_projection(ref data) => {
                 // `<T as TraitRef<..>>::Name`
 
-                // FIXME(#20303) -- gain ability to require that ty_projection : in-scope region,
-                // like a type parameter
+                self.push_projection_constraint_from_top(data);
 
                 // this seems like a minimal requirement:
                 let trait_def = ty::lookup_trait_def(self.tcx, data.trait_ref.def_id);
@@ -211,12 +211,21 @@ fn push_param_constraint_from_top(&mut self,
         self.push_param_constraint(region, opt_ty, param_ty);
     }
 
+    /// Pushes a constraint that `projection_ty` must outlive the top region on the stack.
+    fn push_projection_constraint_from_top(&mut self,
+                                           projection_ty: &ty::ProjectionTy<'tcx>) {
+        let &(region, opt_ty) = self.stack.last().unwrap();
+        self.out.push(RegionSubGenericConstraint(
+            opt_ty, region, GenericKind::Projection(projection_ty.clone())));
+    }
+
     /// Pushes a constraint that `region <= param_ty`, due to `opt_ty`
     fn push_param_constraint(&mut self,
                              region: ty::Region,
                              opt_ty: Option<Ty<'tcx>>,
                              param_ty: ty::ParamTy) {
-        self.out.push(RegionSubParamConstraint(opt_ty, region, param_ty));
+        self.out.push(RegionSubGenericConstraint(
+            opt_ty, region, GenericKind::Param(param_ty)));
     }
 
     fn accumulate_from_adt(&mut self,
@@ -373,16 +382,16 @@ fn accumulate_from_object_ty(&mut self,
 }
 
 impl<'tcx> Repr<'tcx> for WfConstraint<'tcx> {
-    fn repr(&self, tcx: &ty::ctxt) -> String {
+    fn repr(&self, tcx: &ty::ctxt<'tcx>) -> String {
         match *self {
-            RegionSubRegionConstraint(_, r_a, r_b) => {
+            RegionSubRegionConstraint(_, ref r_a, ref r_b) => {
                 format!("RegionSubRegionConstraint({}, {})",
                         r_a.repr(tcx),
                         r_b.repr(tcx))
             }
 
-            RegionSubParamConstraint(_, r, p) => {
-                format!("RegionSubParamConstraint({}, {})",
+            RegionSubGenericConstraint(_, ref r, ref p) => {
+                format!("RegionSubGenericConstraint({}, {})",
                         r.repr(tcx),
                         p.repr(tcx))
             }
index d90bfe04ea1e78ceaa700c888b7a604a2e21f71e..77d71e740d681f8c626bc173e1139b8e87cca468 100644 (file)
@@ -72,20 +72,30 @@ fn visit_item(&mut self, item: &'v ast::Item) {
             ast::ItemImpl(_, _, _, Some(_), _, _) => {
                 // "Trait" impl
                 debug!("coherence2::orphan check: trait impl {}", item.repr(self.tcx));
+                let trait_def_id = ty::impl_trait_ref(self.tcx, def_id).unwrap().def_id;
                 match traits::orphan_check(self.tcx, def_id) {
                     Ok(()) => { }
                     Err(traits::OrphanCheckErr::NoLocalInputType) => {
-                        span_err!(self.tcx.sess, item.span, E0117,
-                                  "cannot provide an extension implementation \
-                                   where both trait and type are not defined in this crate");
+                        if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
+                            let self_ty = ty::lookup_item_type(self.tcx, def_id).ty;
+                            span_err!(
+                                self.tcx.sess, item.span, E0117,
+                                "the type `{}` does not reference any \
+                                 types defined in this crate; \
+                                 only traits defined in the current crate can be \
+                                 implemented for arbitrary types",
+                                self_ty.user_string(self.tcx));
+                        }
                     }
-                    Err(traits::OrphanCheckErr::UncoveredTypeParameter(param_ty)) => {
-                        if !self.tcx.sess.features.borrow().old_orphan_check {
+                    Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
+                        if !ty::has_attr(self.tcx, trait_def_id, "old_orphan_check") {
                             self.tcx.sess.span_err(
                                 item.span,
-                                format!("type parameter `{}` must also appear as a type parameter \
-                                         of some type defined within this crate",
-                                        param_ty.user_string(self.tcx)).as_slice());
+                                format!(
+                                    "type parameter `{}` is not constrained by any local type; \
+                                     only traits defined in the current crate can be implemented \
+                                     for a type parameter",
+                                    param_ty.user_string(self.tcx)).as_slice());
                             self.tcx.sess.span_note(
                                 item.span,
                                 format!("for a limited time, you can add \
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 e01dbac68ee8d8ff6ae82a84c995519914a9fee9..bb9a9ac430340642d193d21293af34296674a4a0 100644 (file)
@@ -2220,7 +2220,7 @@ fn name_from_pat(p: &ast::Pat) -> String {
         PatTup(ref elts) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
                                             .collect::<Vec<String>>().connect(", ")),
         PatBox(ref p) => name_from_pat(&**p),
-        PatRegion(ref p) => name_from_pat(&**p),
+        PatRegion(ref p, _) => name_from_pat(&**p),
         PatLit(..) => {
             warn!("tried to get argument name from PatLit, \
                   which is silly in function arguments");
index 0f0dbf6a24dffc7de58cbf2bdeb6a4fc18a8870c..dcc90117d26606041d1cc721e52e893706df9c8d 100644 (file)
@@ -20,8 +20,8 @@
 
 #[cfg(unix)]
 mod imp {
+    use std::ffi::CString;
     use libc;
-    use std::c_str::ToCStr;
 
     #[cfg(target_os = "linux")]
     mod os {
@@ -111,9 +111,11 @@ pub struct Lock {
 
     impl Lock {
         pub fn new(p: &Path) -> Lock {
-            let fd = p.with_c_str(|s| unsafe {
-                libc::open(s, libc::O_RDWR | libc::O_CREAT, libc::S_IRWXU)
-            });
+            let buf = CString::from_slice(p.as_vec());
+            let fd = unsafe {
+                libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
+                           libc::S_IRWXU)
+            };
             assert!(fd > 0);
             let flock = os::flock {
                 l_start: 0,
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 9d003eca27f3dd11ad067352adb3f048b85b0ac9..3b9265cf569765a39822fea60f54c567ddc9a46a 100644 (file)
@@ -29,7 +29,7 @@
 
 use libc;
 use std::ascii::AsciiExt;
-use std::c_str::ToCStr;
+use std::ffi::CString;
 use std::cell::{RefCell, Cell};
 use std::collections::HashMap;
 use std::fmt;
@@ -215,7 +215,7 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                 let id = id.as_ref().map(|a| a.as_slice());
                 s.push_str(highlight::highlight(text.as_slice(), None, id)
                                      .as_slice());
-                let output = s.to_c_str();
+                let output = CString::from_vec(s.into_bytes());
                 hoedown_buffer_puts(ob, output.as_ptr());
             })
         }
@@ -224,15 +224,16 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
     extern fn header(ob: *mut hoedown_buffer, text: *const hoedown_buffer,
                      level: libc::c_int, opaque: *mut libc::c_void) {
         // hoedown does this, we may as well too
-        "\n".with_c_str(|p| unsafe { hoedown_buffer_puts(ob, p) });
+        unsafe { hoedown_buffer_puts(ob, "\n\0".as_ptr() as *const _); }
 
         // Extract the text provided
         let s = if text.is_null() {
             "".to_string()
         } else {
-            unsafe {
-                String::from_raw_buf_len((*text).data, (*text).size as uint)
-            }
+            let s = unsafe {
+                slice::from_raw_buf(&(*text).data, (*text).size as uint)
+            };
+            str::from_utf8(s).unwrap().to_string()
         };
 
         // Transform the contents of the header into a hyphenated string
@@ -273,7 +274,8 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                                format!("{} ", sec)
                            });
 
-        text.with_c_str(|p| unsafe { hoedown_buffer_puts(ob, p) });
+        let text = CString::from_vec(text.into_bytes());
+        unsafe { hoedown_buffer_puts(ob, text.as_ptr()) }
     }
 
     reset_headers();
index 3accbbfb1a2e79124d91709b8404b667905a9371..ddb14d6944b9d8f358aed8347577e7bf06d57887 100644 (file)
@@ -2253,9 +2253,9 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
             cols += 1;
             tmp /= 10;
         }
-        try!(write!(fmt, "<pre class='line-numbers'>"));
+        try!(write!(fmt, "<pre class=\"line-numbers\">"));
         for i in range(1, lines + 1) {
-            try!(write!(fmt, "<span id='{0}'>{0:1$}</span>\n", i, cols));
+            try!(write!(fmt, "<span id=\"{0}\">{0:1$}</span>\n", i, cols));
         }
         try!(write!(fmt, "</pre>"));
         try!(write!(fmt, "{}", highlight::highlight(s.as_slice(), None, None)));
index 9d4f341a30e25fa018dacb1e0fe9f508cd3c1e09..a5a482541410938bcfbbad6ba50cc27d93170ba2 100644 (file)
@@ -157,6 +157,7 @@ nav.sub {
     left: 0;
     top: 0;
     min-height: 100%;
+    z-index: -1;
 }
 
 .content, nav { max-width: 960px; }
@@ -217,10 +218,18 @@ nav.sub {
     overflow: auto;
     padding-left: 0;
 }
-.content pre.line-numbers { float: left; border: none; }
-.line-numbers span { color: #c67e2d; }
+.content pre.line-numbers {
+    float: left;
+    border: none;
+
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+.line-numbers span { color: #c67e2d; cursor: pointer; }
 .line-numbers .line-highlighted {
-    background-color: #f6fdb0;
+    background-color: #f6fdb0 !important;
 }
 
 .content .highlighted {
@@ -470,6 +479,7 @@ h1 .stability {
 .summary.Unmarked { background-color: #BBBBBB; }
 
 :target { background: #FDFFD3; }
+.line-numbers :target { background-color: transparent; }
 
 /* Code highlighting */
 pre.rust .kw { color: #8959A8; }
index 978af31cdc6895a00ae3527149fc33796d3ec25a..2d575c226c5d0de5d938793553ec7d29ab64ae44 100644 (file)
@@ -50,7 +50,7 @@
     resizeShortBlocks();
     $(window).on('resize', resizeShortBlocks);
 
-    function highlightSourceLines() {
+    function highlightSourceLines(ev) {
         var i, from, to, match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
         if (match) {
             from = parseInt(match[1], 10);
             if ($('#' + from).length === 0) {
                 return;
             }
-            $('#' + from)[0].scrollIntoView();
+            if (ev === null) $('#' + from)[0].scrollIntoView();
             $('.line-numbers span').removeClass('line-highlighted');
             for (i = from; i <= to; ++i) {
                 $('#' + i).addClass('line-highlighted');
             }
         }
     }
-    highlightSourceLines();
+    highlightSourceLines(null);
     $(window).on('hashchange', highlightSourceLines);
 
     $(document).on('keyup', function(e) {
         $("#main > .docblock").before(wrapper);
     });
 
+    $('pre.line-numbers').on('click', 'span', function() {
+        var prev_id = 0;
+
+        function set_fragment(name) {
+            if (history.replaceState) {
+                history.replaceState(null, null, '#' + name);
+                $(window).trigger('hashchange');
+            } else {
+                location.replace('#' + name);
+            }
+        }
+
+        return function(ev) {
+            var cur_id = parseInt(ev.target.id);
+
+            if (ev.shiftKey && prev_id) {
+                if (prev_id > cur_id) {
+                    var tmp = prev_id;
+                    prev_id = cur_id;
+                    cur_id = tmp;
+                }
+
+                set_fragment(prev_id + '-' + cur_id);
+            } else {
+                prev_id = cur_id;
+
+                set_fragment(cur_id);
+            }
+        };
+    }());
+
 }());
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 44bf5f89778703b90b629e34a53985f9ac53afe1..11a49cd712f2557f155bdb09a81d219119faef06 100644 (file)
@@ -70,7 +70,7 @@ pub struct Config {
                                        0123456789-_";
 
 /// A trait for converting a value to base64 encoding.
-pub trait ToBase64 for Sized? {
+pub trait ToBase64 {
     /// Converts the value of `self` to a base64 value following the specified
     /// format configuration, returning the owned string.
     fn to_base64(&self, config: Config) -> String;
@@ -170,7 +170,7 @@ fn to_base64(&self, config: Config) -> String {
 }
 
 /// A trait for converting from base64 encoded values.
-pub trait FromBase64 for Sized? {
+pub trait FromBase64 {
     /// Converts the value of `self`, interpreted as base64 encoded data, into
     /// an owned vector of bytes, returning the vector.
     fn from_base64(&self) -> Result<Vec<u8>, FromBase64Error>;
index c915ddaaa9c041cf2866aac617d7632f8a6ac135..542d0678526b980367b48e41cd8f6ab0545c4a1c 100644 (file)
@@ -18,7 +18,7 @@
 use std::error;
 
 /// A trait for converting a value to hexadecimal encoding
-pub trait ToHex for Sized? {
+pub trait ToHex {
     /// Converts the value of `self` to a hex value, returning the owned
     /// string.
     fn to_hex(&self) -> String;
@@ -54,7 +54,7 @@ fn to_hex(&self) -> String {
 }
 
 /// A trait for converting hexadecimal encoded values
-pub trait FromHex for Sized? {
+pub trait FromHex {
     /// Converts the value of `self`, interpreted as hexadecimal encoded data,
     /// into an owned vector of bytes, returning the vector.
     fn from_hex(&self) -> Result<Vec<u8>, FromHexError>;
index bd4cb1884a69a5b6708de57a5c575ff371877c8b..8b0fb75b438fec3096545be149f17bb760aaa673 100644 (file)
@@ -2302,7 +2302,7 @@ fn error(&mut self, err: &str) -> DecoderError {
 }
 
 /// A trait for converting values to JSON
-pub trait ToJson for Sized? {
+pub trait ToJson {
     /// Converts the value of `self` to an instance of JSON
     fn to_json(&self) -> Json;
 }
index 9932f8d0306b3a81de144241f66df5dd6eff4366..a157d9172749855309f8ab4143cd96957d1dfab8 100644 (file)
@@ -2298,7 +2298,7 @@ fn error(&mut self, err: &str) -> DecoderError {
 }
 
 /// A trait for converting values to JSON
-pub trait ToJson for Sized? {
+pub trait ToJson {
     /// Converts the value of `self` to an instance of JSON
     fn to_json(&self) -> Json;
 }
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 0646ee1758fc0f6b19af44260ab55a5479d14132..a04f67f765108e1a0a0aec7c9202fcdc5828696a 100644 (file)
@@ -190,7 +190,7 @@ fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F)
     fn error(&mut self, err: &str) -> Self::Error;
 }
 
-pub trait Encodable for Sized? {
+pub trait Encodable {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error>;
 }
 
@@ -396,13 +396,13 @@ fn decode<D: Decoder>(d: &mut D) -> Result<(), D::Error> {
     }
 }
 
-impl<'a, Sized? T: Encodable> Encodable for &'a T {
+impl<'a, T: ?Sized + Encodable> Encodable for &'a T {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         (**self).encode(s)
     }
 }
 
-impl<Sized? T: Encodable> Encodable for Box<T> {
+impl<T: ?Sized + Encodable> Encodable for Box<T> {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
         (**self).encode(s)
     }
index 558f9e603e15989fd8ccbd1607761883ffe6d235..fd37bb63230af40d1bc0332328d6f03cc2912845 100644 (file)
@@ -172,7 +172,7 @@ fn read_map_elt_val<T, F>(&mut self, idx: uint, f: F) -> Result<T, E> where
     fn error(&mut self, err: &str) -> E;
 }
 
-pub trait Encodable<S:Encoder<E>, E> for Sized? {
+pub trait Encodable<S:Encoder<E>, E> {
     fn encode(&self, s: &mut S) -> Result<(), E>;
 }
 
@@ -378,13 +378,13 @@ fn decode(d: &mut D) -> Result<(), E> {
     }
 }
 
-impl<'a, E, S: Encoder<E>, Sized? T: Encodable<S, E>> Encodable<S, E> for &'a T {
+impl<'a, E, S: Encoder<E>, T: ?Sized + Encodable<S, E>> Encodable<S, E> for &'a T {
     fn encode(&self, s: &mut S) -> Result<(), E> {
         (**self).encode(s)
     }
 }
 
-impl<E, S: Encoder<E>, Sized? T: Encodable<S, E>> Encodable<S, E> for Box<T> {
+impl<E, S: Encoder<E>, T: ?Sized + Encodable<S, E>> Encodable<S, E> for Box<T> {
     fn encode(&self, s: &mut S) -> Result<(), E> {
         (**self).encode(s)
     }
index bcd87f6786d35dd3e80162865a3c307134b8125b..671408acebf0d51174ab42e8af3478dda4495ebf 100644 (file)
@@ -14,7 +14,6 @@
 
 #![unstable = "unsure about placement and naming"]
 
-use core::kinds::Sized;
 use iter::IteratorExt;
 use ops::FnMut;
 use slice::SliceExt;
@@ -38,7 +37,7 @@ pub trait OwnedAsciiExt {
 
 /// Extension methods for ASCII-subset only operations on string slices
 #[experimental = "would prefer to do this in a more general way"]
-pub trait AsciiExt<T = Self> for Sized? {
+pub trait AsciiExt<T = Self> {
     /// Check if within the ASCII range.
     fn is_ascii(&self) -> bool;
 
@@ -53,7 +52,7 @@ pub trait AsciiExt<T = Self> for Sized? {
     fn to_ascii_lowercase(&self) -> T;
 
     /// Check that two strings are an ASCII case-insensitive match.
-    /// Same as `to_ascii_lowercase(a) == to_ascii_lower(b)`,
+    /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
     /// but without allocating and copying temporary strings.
     fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
 }
index 65cbce08543cc3c84e118f0a4b2fb7ecec1917c6..ed3f2cbe1a1da3f5471e06bb12aa2d0de1f0309d 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![experimental]
-#![macro_escape]
 
 //! A typesafe bitmask flag generator.
 
diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs
deleted file mode 100644 (file)
index 9c96a9c..0000000
+++ /dev/null
@@ -1,857 +0,0 @@
-// Copyright 2012 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.
-
-//! C-string manipulation and management
-//!
-//! This modules provides the basic methods for creating and manipulating
-//! null-terminated strings for use with FFI calls (back to C). Most C APIs require
-//! that the string being passed to them is null-terminated, and by default rust's
-//! string types are *not* null terminated.
-//!
-//! The other problem with translating Rust strings to C strings is that Rust
-//! strings can validly contain a null-byte in the middle of the string (0 is a
-//! valid Unicode codepoint). This means that not all Rust strings can actually be
-//! translated to C strings.
-//!
-//! # Creation of a C string
-//!
-//! A C string is managed through the `CString` type defined in this module. It
-//! "owns" the internal buffer of characters and will automatically deallocate the
-//! buffer when the string is dropped. The `ToCStr` trait is implemented for `&str`
-//! and `&[u8]`, but the conversions can fail due to some of the limitations
-//! explained above.
-//!
-//! This also means that currently whenever a C string is created, an allocation
-//! must be performed to place the data elsewhere (the lifetime of the C string is
-//! not tied to the lifetime of the original string/data buffer). If C strings are
-//! heavily used in applications, then caching may be advisable to prevent
-//! unnecessary amounts of allocations.
-//!
-//! Be carefull to remember that the memory is managed by C allocator API and not
-//! by Rust allocator API.
-//! That means that the CString pointers should be freed with C allocator API
-//! if you intend to do that on your own, as the behaviour if you free them with
-//! Rust's allocator API is not well defined
-//!
-//! An example of creating and using a C string would be:
-//!
-//! ```rust
-//! extern crate libc;
-//!
-//! use std::c_str::ToCStr;
-//!
-//! extern {
-//!     fn puts(s: *const libc::c_char);
-//! }
-//!
-//! fn main() {
-//!     let my_string = "Hello, world!";
-//!
-//!     // Allocate the C string with an explicit local that owns the string. The
-//!     // `c_buffer` pointer will be deallocated when `my_c_string` goes out of scope.
-//!     let my_c_string = my_string.to_c_str();
-//!     unsafe {
-//!         puts(my_c_string.as_ptr());
-//!     }
-//!
-//!     // Don't save/return the pointer to the C string, the `c_buffer` will be
-//!     // deallocated when this block returns!
-//!     my_string.with_c_str(|c_buffer| {
-//!         unsafe { puts(c_buffer); }
-//!     });
-//! }
-//! ```
-
-use core::prelude::*;
-use libc;
-
-use cmp::Ordering;
-use fmt;
-use hash;
-use mem;
-use ptr;
-use slice::{self, IntSliceExt};
-use str;
-use string::String;
-use core::kinds::marker;
-
-/// The representation of a C String.
-///
-/// This structure wraps a `*libc::c_char`, and will automatically free the
-/// memory it is pointing to when it goes out of scope.
-#[allow(missing_copy_implementations)]
-pub struct CString {
-    buf: *const libc::c_char,
-    owns_buffer_: bool,
-}
-
-unsafe impl Send for CString { }
-unsafe impl Sync for CString { }
-
-impl Clone for CString {
-    /// Clone this CString into a new, uniquely owned CString. For safety
-    /// reasons, this is always a deep clone with the memory allocated
-    /// with C's allocator API, rather than the usual shallow clone.
-    fn clone(&self) -> CString {
-        let len = self.len() + 1;
-        let buf = unsafe { libc::malloc(len as libc::size_t) } as *mut libc::c_char;
-        if buf.is_null() { ::alloc::oom() }
-        unsafe { ptr::copy_nonoverlapping_memory(buf, self.buf, len); }
-        CString { buf: buf as *const libc::c_char, owns_buffer_: true }
-    }
-}
-
-impl PartialEq for CString {
-    fn eq(&self, other: &CString) -> bool {
-        // Check if the two strings share the same buffer
-        if self.buf as uint == other.buf as uint {
-            true
-        } else {
-            unsafe {
-                libc::strcmp(self.buf, other.buf) == 0
-            }
-        }
-    }
-}
-
-impl PartialOrd for CString {
-    #[inline]
-    fn partial_cmp(&self, other: &CString) -> Option<Ordering> {
-        self.as_bytes().partial_cmp(other.as_bytes())
-    }
-}
-
-impl Eq for CString {}
-
-impl<S: hash::Writer> hash::Hash<S> for CString {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.as_bytes().hash(state)
-    }
-}
-
-impl CString {
-    /// Create a C String from a pointer, with memory managed by C's allocator
-    /// API, so avoid calling it with a pointer to memory managed by Rust's
-    /// allocator API, as the behaviour would not be well defined.
-    ///
-    ///# Panics
-    ///
-    /// Panics if `buf` is null
-    pub unsafe fn new(buf: *const libc::c_char, owns_buffer: bool) -> CString {
-        assert!(!buf.is_null());
-        CString { buf: buf, owns_buffer_: owns_buffer }
-    }
-
-    /// Return a pointer to the NUL-terminated string data.
-    ///
-    /// `.as_ptr` returns an internal pointer into the `CString`, and
-    /// may be invalidated when the `CString` falls out of scope (the
-    /// destructor will run, freeing the allocation if there is
-    /// one).
-    ///
-    /// ```rust
-    /// use std::c_str::ToCStr;
-    ///
-    /// let foo = "some string";
-    ///
-    /// // right
-    /// let x = foo.to_c_str();
-    /// let p = x.as_ptr();
-    ///
-    /// // wrong (the CString will be freed, invalidating `p`)
-    /// let p = foo.to_c_str().as_ptr();
-    /// ```
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// extern crate libc;
-    ///
-    /// use std::c_str::ToCStr;
-    ///
-    /// fn main() {
-    ///     let c_str = "foo bar".to_c_str();
-    ///     unsafe {
-    ///         libc::puts(c_str.as_ptr());
-    ///     }
-    /// }
-    /// ```
-    pub fn as_ptr(&self) -> *const libc::c_char {
-        self.buf
-    }
-
-    /// Return a mutable pointer to the NUL-terminated string data.
-    ///
-    /// `.as_mut_ptr` returns an internal pointer into the `CString`, and
-    /// may be invalidated when the `CString` falls out of scope (the
-    /// destructor will run, freeing the allocation if there is
-    /// one).
-    ///
-    /// ```rust
-    /// use std::c_str::ToCStr;
-    ///
-    /// let foo = "some string";
-    ///
-    /// // right
-    /// let mut x = foo.to_c_str();
-    /// let p = x.as_mut_ptr();
-    ///
-    /// // wrong (the CString will be freed, invalidating `p`)
-    /// let p = foo.to_c_str().as_mut_ptr();
-    /// ```
-    pub fn as_mut_ptr(&mut self) -> *mut libc::c_char {
-        self.buf as *mut _
-    }
-
-    /// Returns whether or not the `CString` owns the buffer.
-    pub fn owns_buffer(&self) -> bool {
-        self.owns_buffer_
-    }
-
-    /// Converts the CString into a `&[u8]` without copying.
-    /// Includes the terminating NUL byte.
-    #[inline]
-    pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
-        unsafe {
-            slice::from_raw_buf(&self.buf, self.len() + 1).as_unsigned()
-        }
-    }
-
-    /// Converts the CString into a `&[u8]` without copying.
-    /// Does not include the terminating NUL byte.
-    #[inline]
-    pub fn as_bytes_no_nul<'a>(&'a self) -> &'a [u8] {
-        unsafe {
-            slice::from_raw_buf(&self.buf, self.len()).as_unsigned()
-        }
-    }
-
-    /// Converts the CString into a `&str` without copying.
-    /// Returns None if the CString is not UTF-8.
-    #[inline]
-    pub fn as_str<'a>(&'a self) -> Option<&'a str> {
-        let buf = self.as_bytes_no_nul();
-        str::from_utf8(buf).ok()
-    }
-
-    /// Return a CString iterator.
-    pub fn iter<'a>(&'a self) -> CChars<'a> {
-        CChars {
-            ptr: self.buf,
-            marker: marker::ContravariantLifetime,
-        }
-    }
-
-    /// Unwraps the wrapped `*libc::c_char` from the `CString` wrapper.
-    ///
-    /// Any ownership of the buffer by the `CString` wrapper is
-    /// forgotten, meaning that the backing allocation of this
-    /// `CString` is not automatically freed if it owns the
-    /// allocation. In this case, a user of `.unwrap()` should ensure
-    /// the allocation is freed, to avoid leaking memory. You should
-    /// use libc's memory allocator in this case.
-    ///
-    /// Prefer `.as_ptr()` when just retrieving a pointer to the
-    /// string data, as that does not relinquish ownership.
-    pub unsafe fn into_inner(mut self) -> *const libc::c_char {
-        self.owns_buffer_ = false;
-        self.buf
-    }
-
-    /// Return the number of bytes in the CString (not including the NUL
-    /// terminator).
-    #[inline]
-    pub fn len(&self) -> uint {
-        unsafe { libc::strlen(self.buf) as uint }
-    }
-
-    /// Returns if there are no bytes in this string
-    #[inline]
-    pub fn is_empty(&self) -> bool { self.len() == 0 }
-}
-
-impl Drop for CString {
-    fn drop(&mut self) {
-        if self.owns_buffer_ {
-            unsafe {
-                libc::free(self.buf as *mut libc::c_void)
-            }
-        }
-    }
-}
-
-impl fmt::Show for CString {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        String::from_utf8_lossy(self.as_bytes_no_nul()).fmt(f)
-    }
-}
-
-/// A generic trait for converting a value to a CString.
-pub trait ToCStr for Sized? {
-    /// Copy the receiver into a CString.
-    ///
-    /// # Panics
-    ///
-    /// Panics the task if the receiver has an interior null.
-    fn to_c_str(&self) -> CString;
-
-    /// Unsafe variant of `to_c_str()` that doesn't check for nulls.
-    unsafe fn to_c_str_unchecked(&self) -> CString;
-
-    /// Work with a temporary CString constructed from the receiver.
-    /// The provided `*libc::c_char` will be freed immediately upon return.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// extern crate libc;
-    ///
-    /// use std::c_str::ToCStr;
-    ///
-    /// fn main() {
-    ///     let s = "PATH".with_c_str(|path| unsafe {
-    ///         libc::getenv(path)
-    ///     });
-    /// }
-    /// ```
-    ///
-    /// # Panics
-    ///
-    /// Panics the task if the receiver has an interior null.
-    #[inline]
-    fn with_c_str<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        let c_str = self.to_c_str();
-        f(c_str.as_ptr())
-    }
-
-    /// Unsafe variant of `with_c_str()` that doesn't check for nulls.
-    #[inline]
-    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        let c_str = self.to_c_str_unchecked();
-        f(c_str.as_ptr())
-    }
-}
-
-impl ToCStr for str {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        self.as_bytes().to_c_str()
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        self.as_bytes().to_c_str_unchecked()
-    }
-
-    #[inline]
-    fn with_c_str<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        self.as_bytes().with_c_str(f)
-    }
-
-    #[inline]
-    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        self.as_bytes().with_c_str_unchecked(f)
-    }
-}
-
-impl ToCStr for String {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        self.as_bytes().to_c_str()
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        self.as_bytes().to_c_str_unchecked()
-    }
-
-    #[inline]
-    fn with_c_str<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        self.as_bytes().with_c_str(f)
-    }
-
-    #[inline]
-    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        self.as_bytes().with_c_str_unchecked(f)
-    }
-}
-
-// The length of the stack allocated buffer for `vec.with_c_str()`
-const BUF_LEN: uint = 128;
-
-impl ToCStr for [u8] {
-    fn to_c_str(&self) -> CString {
-        let mut cs = unsafe { self.to_c_str_unchecked() };
-        check_for_null(self, cs.as_mut_ptr());
-        cs
-    }
-
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        let self_len = self.len();
-        let buf = libc::malloc(self_len as libc::size_t + 1) as *mut u8;
-        if buf.is_null() { ::alloc::oom() }
-
-        ptr::copy_memory(buf, self.as_ptr(), self_len);
-        *buf.offset(self_len as int) = 0;
-
-        CString::new(buf as *const libc::c_char, true)
-    }
-
-    fn with_c_str<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        unsafe { with_c_str(self, true, f) }
-    }
-
-    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        with_c_str(self, false, f)
-    }
-}
-
-impl<'a, Sized? T: ToCStr> ToCStr for &'a T {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        (**self).to_c_str()
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        (**self).to_c_str_unchecked()
-    }
-
-    #[inline]
-    fn with_c_str<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        (**self).with_c_str(f)
-    }
-
-    #[inline]
-    unsafe fn with_c_str_unchecked<T, F>(&self, f: F) -> T where
-        F: FnOnce(*const libc::c_char) -> T,
-    {
-        (**self).with_c_str_unchecked(f)
-    }
-}
-
-// Unsafe function that handles possibly copying the &[u8] into a stack array.
-unsafe fn with_c_str<T, F>(v: &[u8], checked: bool, f: F) -> T where
-    F: FnOnce(*const libc::c_char) -> T,
-{
-    let c_str = if v.len() < BUF_LEN {
-        let mut buf: [u8; BUF_LEN] = mem::uninitialized();
-        slice::bytes::copy_memory(&mut buf, v);
-        buf[v.len()] = 0;
-
-        let buf = buf.as_mut_ptr();
-        if checked {
-            check_for_null(v, buf as *mut libc::c_char);
-        }
-
-        return f(buf as *const libc::c_char)
-    } else if checked {
-        v.to_c_str()
-    } else {
-        v.to_c_str_unchecked()
-    };
-
-    f(c_str.as_ptr())
-}
-
-#[inline]
-fn check_for_null(v: &[u8], buf: *mut libc::c_char) {
-    for i in range(0, v.len()) {
-        unsafe {
-            let p = buf.offset(i as int);
-            assert!(*p != 0);
-        }
-    }
-}
-
-/// External iterator for a CString's bytes.
-///
-/// Use with the `std::iter` module.
-#[allow(raw_pointer_deriving)]
-#[derive(Clone)]
-pub struct CChars<'a> {
-    ptr: *const libc::c_char,
-    marker: marker::ContravariantLifetime<'a>,
-}
-
-impl<'a> Iterator for CChars<'a> {
-    type Item = libc::c_char;
-
-    fn next(&mut self) -> Option<libc::c_char> {
-        let ch = unsafe { *self.ptr };
-        if ch == 0 {
-            None
-        } else {
-            self.ptr = unsafe { self.ptr.offset(1) };
-            Some(ch)
-        }
-    }
-}
-
-/// Parses a C "multistring", eg windows env values or
-/// the req->ptr result in a uv_fs_readdir() call.
-///
-/// Optionally, a `count` can be passed in, limiting the
-/// parsing to only being done `count`-times.
-///
-/// The specified closure is invoked with each string that
-/// is found, and the number of strings found is returned.
-pub unsafe fn from_c_multistring<F>(buf: *const libc::c_char,
-                                    count: Option<uint>,
-                                    mut f: F)
-                                    -> uint where
-    F: FnMut(&CString),
-{
-
-    let mut curr_ptr: uint = buf as uint;
-    let mut ctr = 0;
-    let (limited_count, limit) = match count {
-        Some(limit) => (true, limit),
-        None => (false, 0)
-    };
-    while ((limited_count && ctr < limit) || !limited_count)
-          && *(curr_ptr as *const libc::c_char) != 0 as libc::c_char {
-        let cstr = CString::new(curr_ptr as *const libc::c_char, false);
-        f(&cstr);
-        curr_ptr += cstr.len() + 1;
-        ctr += 1;
-    }
-    return ctr;
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::v1::*;
-    use super::*;
-    use ptr;
-    use thread::Thread;
-    use libc;
-
-    #[test]
-    fn test_str_multistring_parsing() {
-        unsafe {
-            let input = b"zero\0one\0\0";
-            let ptr = input.as_ptr();
-            let expected = ["zero", "one"];
-            let mut it = expected.iter();
-            let result = from_c_multistring(ptr as *const libc::c_char, None, |c| {
-                let cbytes = c.as_bytes_no_nul();
-                assert_eq!(cbytes, it.next().unwrap().as_bytes());
-            });
-            assert_eq!(result, 2);
-            assert!(it.next().is_none());
-        }
-    }
-
-    #[test]
-    fn test_str_to_c_str() {
-        let c_str = "".to_c_str();
-        unsafe {
-            assert_eq!(*c_str.as_ptr().offset(0), 0);
-        }
-
-        let c_str = "hello".to_c_str();
-        let buf = c_str.as_ptr();
-        unsafe {
-            assert_eq!(*buf.offset(0), 'h' as libc::c_char);
-            assert_eq!(*buf.offset(1), 'e' as libc::c_char);
-            assert_eq!(*buf.offset(2), 'l' as libc::c_char);
-            assert_eq!(*buf.offset(3), 'l' as libc::c_char);
-            assert_eq!(*buf.offset(4), 'o' as libc::c_char);
-            assert_eq!(*buf.offset(5), 0);
-        }
-    }
-
-    #[test]
-    fn test_vec_to_c_str() {
-        let b: &[u8] = &[];
-        let c_str = b.to_c_str();
-        unsafe {
-            assert_eq!(*c_str.as_ptr().offset(0), 0);
-        }
-
-        let c_str = b"hello".to_c_str();
-        let buf = c_str.as_ptr();
-        unsafe {
-            assert_eq!(*buf.offset(0), 'h' as libc::c_char);
-            assert_eq!(*buf.offset(1), 'e' as libc::c_char);
-            assert_eq!(*buf.offset(2), 'l' as libc::c_char);
-            assert_eq!(*buf.offset(3), 'l' as libc::c_char);
-            assert_eq!(*buf.offset(4), 'o' as libc::c_char);
-            assert_eq!(*buf.offset(5), 0);
-        }
-
-        let c_str = b"foo\xFF".to_c_str();
-        let buf = c_str.as_ptr();
-        unsafe {
-            assert_eq!(*buf.offset(0), 'f' as libc::c_char);
-            assert_eq!(*buf.offset(1), 'o' as libc::c_char);
-            assert_eq!(*buf.offset(2), 'o' as libc::c_char);
-            assert_eq!(*buf.offset(3), 0xffu8 as libc::c_char);
-            assert_eq!(*buf.offset(4), 0);
-        }
-    }
-
-    #[test]
-    fn test_unwrap() {
-        let c_str = "hello".to_c_str();
-        unsafe { libc::free(c_str.into_inner() as *mut libc::c_void) }
-    }
-
-    #[test]
-    fn test_as_ptr() {
-        let c_str = "hello".to_c_str();
-        let len = unsafe { libc::strlen(c_str.as_ptr()) };
-        assert_eq!(len, 5);
-    }
-
-    #[test]
-    fn test_iterator() {
-        let c_str = "".to_c_str();
-        let mut iter = c_str.iter();
-        assert_eq!(iter.next(), None);
-
-        let c_str = "hello".to_c_str();
-        let mut iter = c_str.iter();
-        assert_eq!(iter.next(), Some('h' as libc::c_char));
-        assert_eq!(iter.next(), Some('e' as libc::c_char));
-        assert_eq!(iter.next(), Some('l' as libc::c_char));
-        assert_eq!(iter.next(), Some('l' as libc::c_char));
-        assert_eq!(iter.next(), Some('o' as libc::c_char));
-        assert_eq!(iter.next(), None);
-    }
-
-    #[test]
-    fn test_to_c_str_fail() {
-        assert!(Thread::spawn(move|| { "he\x00llo".to_c_str() }).join().is_err());
-    }
-
-    #[test]
-    fn test_to_c_str_unchecked() {
-        unsafe {
-            let c_string = "he\x00llo".to_c_str_unchecked();
-            let buf = c_string.as_ptr();
-            assert_eq!(*buf.offset(0), 'h' as libc::c_char);
-            assert_eq!(*buf.offset(1), 'e' as libc::c_char);
-            assert_eq!(*buf.offset(2), 0);
-            assert_eq!(*buf.offset(3), 'l' as libc::c_char);
-            assert_eq!(*buf.offset(4), 'l' as libc::c_char);
-            assert_eq!(*buf.offset(5), 'o' as libc::c_char);
-            assert_eq!(*buf.offset(6), 0);
-        }
-    }
-
-    #[test]
-    fn test_as_bytes() {
-        let c_str = "hello".to_c_str();
-        assert_eq!(c_str.as_bytes(), b"hello\0");
-        let c_str = "".to_c_str();
-        assert_eq!(c_str.as_bytes(), b"\0");
-        let c_str = b"foo\xFF".to_c_str();
-        assert_eq!(c_str.as_bytes(), b"foo\xFF\0");
-    }
-
-    #[test]
-    fn test_as_bytes_no_nul() {
-        let c_str = "hello".to_c_str();
-        assert_eq!(c_str.as_bytes_no_nul(), b"hello");
-        let c_str = "".to_c_str();
-        let exp: &[u8] = &[];
-        assert_eq!(c_str.as_bytes_no_nul(), exp);
-        let c_str = b"foo\xFF".to_c_str();
-        assert_eq!(c_str.as_bytes_no_nul(), b"foo\xFF");
-    }
-
-    #[test]
-    fn test_as_str() {
-        let c_str = "hello".to_c_str();
-        assert_eq!(c_str.as_str(), Some("hello"));
-        let c_str = "".to_c_str();
-        assert_eq!(c_str.as_str(), Some(""));
-        let c_str = b"foo\xFF".to_c_str();
-        assert_eq!(c_str.as_str(), None);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_new_fail() {
-        let _c_str = unsafe { CString::new(ptr::null(), false) };
-    }
-
-    #[test]
-    fn test_clone() {
-        let a = "hello".to_c_str();
-        let b = a.clone();
-        assert!(a == b);
-    }
-
-    #[test]
-    fn test_clone_noleak() {
-        fn foo<F>(f: F) where F: FnOnce(&CString) {
-            let s = "test".to_string();
-            let c = s.to_c_str();
-            // give the closure a non-owned CString
-            let mut c_ = unsafe { CString::new(c.as_ptr(), false) };
-            f(&c_);
-            // muck with the buffer for later printing
-            unsafe { *c_.as_mut_ptr() = 'X' as libc::c_char }
-        }
-
-        let mut c_: Option<CString> = None;
-        foo(|c| {
-            c_ = Some(c.clone());
-            c.clone();
-            // force a copy, reading the memory
-            c.as_bytes().to_vec();
-        });
-        let c_ = c_.unwrap();
-        // force a copy, reading the memory
-        c_.as_bytes().to_vec();
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-
-    use prelude::v1::*;
-    use self::test::Bencher;
-    use libc;
-    use c_str::ToCStr;
-
-    #[inline]
-    fn check(s: &str, c_str: *const libc::c_char) {
-        let s_buf = s.as_ptr();
-        for i in range(0, s.len()) {
-            unsafe {
-                assert_eq!(
-                    *s_buf.offset(i as int) as libc::c_char,
-                    *c_str.offset(i as int));
-            }
-        }
-    }
-
-    static S_SHORT: &'static str = "Mary";
-    static S_MEDIUM: &'static str = "Mary had a little lamb";
-    static S_LONG: &'static str = "\
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb";
-
-    fn bench_to_string(b: &mut Bencher, s: &str) {
-        b.iter(|| {
-            let c_str = s.to_c_str();
-            check(s, c_str.as_ptr());
-        })
-    }
-
-    #[bench]
-    fn bench_to_c_str_short(b: &mut Bencher) {
-        bench_to_string(b, S_SHORT)
-    }
-
-    #[bench]
-    fn bench_to_c_str_medium(b: &mut Bencher) {
-        bench_to_string(b, S_MEDIUM)
-    }
-
-    #[bench]
-    fn bench_to_c_str_long(b: &mut Bencher) {
-        bench_to_string(b, S_LONG)
-    }
-
-    fn bench_to_c_str_unchecked(b: &mut Bencher, s: &str) {
-        b.iter(|| {
-            let c_str = unsafe { s.to_c_str_unchecked() };
-            check(s, c_str.as_ptr())
-        })
-    }
-
-    #[bench]
-    fn bench_to_c_str_unchecked_short(b: &mut Bencher) {
-        bench_to_c_str_unchecked(b, S_SHORT)
-    }
-
-    #[bench]
-    fn bench_to_c_str_unchecked_medium(b: &mut Bencher) {
-        bench_to_c_str_unchecked(b, S_MEDIUM)
-    }
-
-    #[bench]
-    fn bench_to_c_str_unchecked_long(b: &mut Bencher) {
-        bench_to_c_str_unchecked(b, S_LONG)
-    }
-
-    fn bench_with_c_str(b: &mut Bencher, s: &str) {
-        b.iter(|| {
-            s.with_c_str(|c_str_buf| check(s, c_str_buf))
-        })
-    }
-
-    #[bench]
-    fn bench_with_c_str_short(b: &mut Bencher) {
-        bench_with_c_str(b, S_SHORT)
-    }
-
-    #[bench]
-    fn bench_with_c_str_medium(b: &mut Bencher) {
-        bench_with_c_str(b, S_MEDIUM)
-    }
-
-    #[bench]
-    fn bench_with_c_str_long(b: &mut Bencher) {
-        bench_with_c_str(b, S_LONG)
-    }
-
-    fn bench_with_c_str_unchecked(b: &mut Bencher, s: &str) {
-        b.iter(|| {
-            unsafe {
-                s.with_c_str_unchecked(|c_str_buf| check(s, c_str_buf))
-            }
-        })
-    }
-
-    #[bench]
-    fn bench_with_c_str_unchecked_short(b: &mut Bencher) {
-        bench_with_c_str_unchecked(b, S_SHORT)
-    }
-
-    #[bench]
-    fn bench_with_c_str_unchecked_medium(b: &mut Bencher) {
-        bench_with_c_str_unchecked(b, S_MEDIUM)
-    }
-
-    #[bench]
-    fn bench_with_c_str_unchecked_long(b: &mut Bencher) {
-        bench_with_c_str_unchecked(b, S_LONG)
-    }
-}
diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs
deleted file mode 100644 (file)
index 4a20208..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-// Copyright 2012 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.
-
-//! Library to interface with chunks of memory allocated in C.
-//!
-//! It is often desirable to safely interface with memory allocated from C,
-//! encapsulating the unsafety into allocation and destruction time.  Indeed,
-//! allocating memory externally is currently the only way to give Rust shared
-//! mut state with C programs that keep their own references; vectors are
-//! unsuitable because they could be reallocated or moved at any time, and
-//! importing C memory into a vector takes a one-time snapshot of the memory.
-//!
-//! This module simplifies the usage of such external blocks of memory.  Memory
-//! is encapsulated into an opaque object after creation; the lifecycle of the
-//! memory can be optionally managed by Rust, if an appropriate destructor
-//! closure is provided.  Safety is ensured by bounds-checking accesses, which
-//! are marshalled through get and set functions.
-//!
-//! There are three unsafe functions: the two constructors, and the
-//! unwrap method. The constructors are unsafe for the
-//! obvious reason (they act on a pointer that cannot be checked inside the
-//! method), but `unwrap()` is somewhat more subtle in its unsafety.
-//! It returns the contained pointer, but at the same time destroys the CVec
-//! without running its destructor. This can be used to pass memory back to
-//! C, but care must be taken that the ownership of underlying resources are
-//! handled correctly, i.e. that allocated memory is eventually freed
-//! if necessary.
-
-#![experimental]
-
-use kinds::Send;
-use mem;
-use ops::{Drop, FnOnce};
-use option::Option;
-use option::Option::{Some, None};
-use ptr::PtrExt;
-use ptr;
-use raw;
-use slice::AsSlice;
-use thunk::{Thunk};
-
-/// The type representing a foreign chunk of memory
-pub struct CVec<T> {
-    base: *mut T,
-    len: uint,
-    dtor: Option<Thunk>,
-}
-
-#[unsafe_destructor]
-impl<T> Drop for CVec<T> {
-    fn drop(&mut self) {
-        match self.dtor.take() {
-            None => (),
-            Some(f) => f.invoke(())
-        }
-    }
-}
-
-impl<T> CVec<T> {
-    /// Create a `CVec` from a raw pointer to a buffer with a given length.
-    ///
-    /// Panics if the given pointer is null. The returned vector will not attempt
-    /// to deallocate the vector when dropped.
-    ///
-    /// # Arguments
-    ///
-    /// * base - A raw pointer to a buffer
-    /// * len - The number of elements in the buffer
-    pub unsafe fn new(base: *mut T, len: uint) -> CVec<T> {
-        assert!(base != ptr::null_mut());
-        CVec {
-            base: base,
-            len: len,
-            dtor: None,
-        }
-    }
-
-    /// Create a `CVec` from a foreign buffer, with a given length,
-    /// and a function to run upon destruction.
-    ///
-    /// Panics if the given pointer is null.
-    ///
-    /// # Arguments
-    ///
-    /// * base - A foreign pointer to a buffer
-    /// * len - The number of elements in the buffer
-    /// * dtor - A fn to run when the value is destructed, useful
-    ///          for freeing the buffer, etc.
-    pub unsafe fn new_with_dtor<F>(base: *mut T,
-                                   len: uint,
-                                   dtor: F)
-                                   -> CVec<T>
-        where F : FnOnce(), F : Send
-    {
-        assert!(base != ptr::null_mut());
-        let dtor: Thunk = Thunk::new(dtor);
-        CVec {
-            base: base,
-            len: len,
-            dtor: Some(dtor)
-        }
-    }
-
-    /// View the stored data as a mutable slice.
-    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
-        unsafe {
-            mem::transmute(raw::Slice { data: self.base as *const T, len: self.len })
-        }
-    }
-
-    /// Retrieves an element at a given index, returning `None` if the requested
-    /// index is greater than the length of the vector.
-    pub fn get<'a>(&'a self, ofs: uint) -> Option<&'a T> {
-        if ofs < self.len {
-            Some(unsafe { &*self.base.offset(ofs as int) })
-        } else {
-            None
-        }
-    }
-
-    /// Retrieves a mutable element at a given index, returning `None` if the
-    /// requested index is greater than the length of the vector.
-    pub fn get_mut<'a>(&'a mut self, ofs: uint) -> Option<&'a mut T> {
-        if ofs < self.len {
-            Some(unsafe { &mut *self.base.offset(ofs as int) })
-        } else {
-            None
-        }
-    }
-
-    /// Unwrap the pointer without running the destructor
-    ///
-    /// This method retrieves the underlying pointer, and in the process
-    /// destroys the CVec but without running the destructor. A use case
-    /// would be transferring ownership of the buffer to a C function, as
-    /// in this case you would not want to run the destructor.
-    ///
-    /// Note that if you want to access the underlying pointer without
-    /// cancelling the destructor, you can simply call `transmute` on the return
-    /// value of `get(0)`.
-    pub unsafe fn into_inner(mut self) -> *mut T {
-        self.dtor = None;
-        self.base
-    }
-
-    /// Returns the number of items in this vector.
-    pub fn len(&self) -> uint { self.len }
-
-    /// Returns whether this vector is empty.
-    pub fn is_empty(&self) -> bool { self.len() == 0 }
-}
-
-impl<T> AsSlice<T> for CVec<T> {
-    /// View the stored data as a slice.
-    fn as_slice<'a>(&'a self) -> &'a [T] {
-        unsafe {
-            mem::transmute(raw::Slice { data: self.base as *const T, len: self.len })
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::v1::*;
-
-    use super::CVec;
-    use libc;
-    use ptr;
-
-    fn malloc(n: uint) -> CVec<u8> {
-        unsafe {
-            let mem = ptr::Unique(libc::malloc(n as libc::size_t));
-            if mem.0.is_null() { ::alloc::oom() }
-
-            CVec::new_with_dtor(mem.0 as *mut u8,
-                                n,
-                                move|| { libc::free(mem.0 as *mut libc::c_void); })
-        }
-    }
-
-    #[test]
-    fn test_basic() {
-        let mut cv = malloc(16);
-
-        *cv.get_mut(3).unwrap() = 8;
-        *cv.get_mut(4).unwrap() = 9;
-        assert_eq!(*cv.get(3).unwrap(), 8);
-        assert_eq!(*cv.get(4).unwrap(), 9);
-        assert_eq!(cv.len(), 16);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_panic_at_null() {
-        unsafe {
-            CVec::new(ptr::null_mut::<u8>(), 9);
-        }
-    }
-
-    #[test]
-    fn test_overrun_get() {
-        let cv = malloc(16);
-
-        assert!(cv.get(17).is_none());
-    }
-
-    #[test]
-    fn test_overrun_set() {
-        let mut cv = malloc(16);
-
-        assert!(cv.get_mut(17).is_none());
-    }
-
-    #[test]
-    fn test_unwrap() {
-        unsafe {
-            let cv = CVec::new_with_dtor(1 as *mut int,
-                                         0,
-                                         move|:| panic!("Don't run this destructor!"));
-            let p = cv.into_inner();
-            assert_eq!(p, 1 as *mut int);
-        }
-    }
-
-}
index c35be86420de87e1ca2849e1309195904190346f..a3fc38c34e84fb70deb3f094cfdf0f745b32e29c 100644 (file)
@@ -440,14 +440,14 @@ fn into_option(self) -> Option<FullBucket<K, V, M>> {
 }
 
 impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
-    fn make_hash<Sized? X: Hash<S>>(&self, x: &X) -> SafeHash {
+    fn make_hash<X: ?Sized + Hash<S>>(&self, x: &X) -> SafeHash {
         table::make_hash(&self.hasher, x)
     }
 
     /// Search for a key, yielding the index if it's found in the hashtable.
     /// If you already have the hash for the key lying around, use
     /// search_hashed.
-    fn search<'a, Sized? Q>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
+    fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
         where Q: BorrowFrom<K> + Eq + Hash<S>
     {
         let hash = self.make_hash(q);
@@ -455,7 +455,7 @@ fn search<'a, Sized? Q>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
             .into_option()
     }
 
-    fn search_mut<'a, Sized? Q>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
+    fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
         where Q: BorrowFrom<K> + Eq + Hash<S>
     {
         let hash = self.make_hash(q);
@@ -923,7 +923,7 @@ fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
     #[stable]
     /// Gets the given key's corresponding entry in the map for in-place manipulation.
     /// Regardless of whether or not `to_owned()` has been called, the key must hash the same way.
-    pub fn entry<'a, Sized? Q>(&'a mut self, key: &'a Q) -> Entry<'a, Q, K, V>
+    pub fn entry<'a, Q: ?Sized>(&'a mut self, key: &'a Q) -> Entry<'a, Q, K, V>
         where Q: Eq + Hash<S> + ToOwned<K>
     {
         // Gotta resize now.
@@ -1030,7 +1030,7 @@ pub fn clear(&mut self) {
     /// assert_eq!(map.get(&2), None);
     /// ```
     #[stable]
-    pub fn get<Sized? Q>(&self, k: &Q) -> Option<&V>
+    pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
         where Q: Hash<S> + Eq + BorrowFrom<K>
     {
         self.search(k).map(|bucket| bucket.into_refs().1)
@@ -1053,7 +1053,7 @@ pub fn get<Sized? Q>(&self, k: &Q) -> Option<&V>
     /// assert_eq!(map.contains_key(&2), false);
     /// ```
     #[stable]
-    pub fn contains_key<Sized? Q>(&self, k: &Q) -> bool
+    pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
         where Q: Hash<S> + Eq + BorrowFrom<K>
     {
         self.search(k).is_some()
@@ -1079,7 +1079,7 @@ pub fn contains_key<Sized? Q>(&self, k: &Q) -> bool
     /// assert_eq!(map[1], "b");
     /// ```
     #[stable]
-    pub fn get_mut<Sized? Q>(&mut self, k: &Q) -> Option<&mut V>
+    pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
         where Q: Hash<S> + Eq + BorrowFrom<K>
     {
         self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
@@ -1131,7 +1131,7 @@ pub fn insert(&mut self, k: K, v: V) -> Option<V> {
     /// assert_eq!(map.remove(&1), None);
     /// ```
     #[stable]
-    pub fn remove<Sized? Q>(&mut self, k: &Q) -> Option<V>
+    pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
         where Q: Hash<S> + Eq + BorrowFrom<K>
     {
         if self.table.size() == 0 {
@@ -1142,7 +1142,7 @@ pub fn remove<Sized? Q>(&mut self, k: &Q) -> Option<V>
     }
 }
 
-fn search_entry_hashed<'a, K, V, Sized? Q>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: &'a Q)
+fn search_entry_hashed<'a, K, V, Q: ?Sized>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: &'a Q)
         -> Entry<'a, Q, K, V>
     where Q: Eq + ToOwned<K>
 {
@@ -1227,7 +1227,7 @@ fn default() -> HashMap<K, V, H> {
 }
 
 #[stable]
-impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> Index<Q> for HashMap<K, V, H>
+impl<K: Hash<S> + Eq, Q: ?Sized, V, S, H: Hasher<S>> Index<Q> for HashMap<K, V, H>
     where Q: BorrowFrom<K> + Hash<S> + Eq
 {
     type Output = V;
@@ -1239,7 +1239,7 @@ fn index<'a>(&'a self, index: &Q) -> &'a V {
 }
 
 #[stable]
-impl<K: Hash<S> + Eq, Sized? Q, V, S, H: Hasher<S>> IndexMut<Q> for HashMap<K, V, H>
+impl<K: Hash<S> + Eq, Q: ?Sized, V, S, H: Hasher<S>> IndexMut<Q> for HashMap<K, V, H>
     where Q: BorrowFrom<K> + Hash<S> + Eq
 {
     type Output = V;
@@ -1331,7 +1331,7 @@ pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
 
 #[stable]
 /// A view into a single empty location in a HashMap
-pub struct VacantEntry<'a, Sized? Q: 'a, K: 'a, V: 'a> {
+pub struct VacantEntry<'a, Q: ?Sized + 'a, K: 'a, V: 'a> {
     hash: SafeHash,
     key: &'a Q,
     elem: VacantEntryState<K, V, &'a mut RawTable<K, V>>,
@@ -1339,7 +1339,7 @@ pub struct VacantEntry<'a, Sized? Q: 'a, K: 'a, V: 'a> {
 
 #[stable]
 /// A view into a single location in a map, which may be vacant or occupied
-pub enum Entry<'a, Sized? Q: 'a, K: 'a, V: 'a> {
+pub enum Entry<'a, Q: ?Sized + 'a, K: 'a, V: 'a> {
     /// An occupied Entry
     Occupied(OccupiedEntry<'a, K, V>),
     /// A vacant Entry
@@ -1409,7 +1409,7 @@ fn size_hint(&self) -> (uint, Option<uint>) {
     }
 }
 
-impl<'a, Sized? Q, K, V> Entry<'a, Q, K, V> {
+impl<'a, Q: ?Sized, K, V> Entry<'a, Q, K, V> {
     #[unstable = "matches collection reform v2 specification, waiting for dust to settle"]
     /// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
     pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, Q, K, V>> {
@@ -1455,7 +1455,7 @@ pub fn remove(self) -> V {
     }
 }
 
-impl<'a, Sized? Q: 'a + ToOwned<K>, K: 'a, V: 'a> VacantEntry<'a, Q, K, V> {
+impl<'a, Q: ?Sized + 'a + ToOwned<K>, K: 'a, V: 'a> VacantEntry<'a, Q, K, V> {
     #[stable]
     /// Sets the value of the entry with the VacantEntry's key,
     /// and returns a mutable reference to it
@@ -1482,7 +1482,7 @@ fn from_iter<T: Iterator<Item=(K, V)>>(iter: T) -> HashMap<K, V, H> {
 }
 
 #[stable]
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extend<(K, V)> for HashMap<K, V, H> {
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Extend<(K, V)> for HashMap<K, V, H> {
     fn extend<T: Iterator<Item=(K, V)>>(&mut self, mut iter: T) {
         for (k, v) in iter {
             self.insert(k, v);
index b1824db93aad120faec507751c130125ad431919..211bfe2c10e8fede558452f3c9a12918bd60054c 100644 (file)
 use fmt::Show;
 use fmt;
 use hash::{Hash, Hasher, RandomSipHasher};
-use iter::{Iterator, IteratorExt, IteratorCloneExt, FromIterator, Map, Chain, Extend};
+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};
 
@@ -451,7 +453,7 @@ pub fn clear(&mut self) { self.map.clear() }
     /// assert_eq!(set.contains(&4), false);
     /// ```
     #[stable]
-    pub fn contains<Sized? Q>(&self, value: &Q) -> bool
+    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
         where Q: BorrowFrom<T> + Hash<S> + Eq
     {
         self.map.contains_key(value)
@@ -561,7 +563,7 @@ pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none(
     /// assert_eq!(set.remove(&2), false);
     /// ```
     #[stable]
-    pub fn remove<Sized? Q>(&mut self, value: &Q) -> bool
+    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
         where Q: BorrowFrom<T> + Hash<S> + Eq
     {
         self.map.remove(value).is_some()
@@ -605,7 +607,7 @@ fn from_iter<I: Iterator<Item=T>>(iter: I) -> HashSet<T, H> {
 }
 
 #[stable]
-impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extend<T> for HashSet<T, H> {
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> Extend<T> for HashSet<T, H> {
     fn extend<I: Iterator<Item=T>>(&mut self, mut iter: I) {
         for k in iter {
             self.insert(k);
index ab91beb4f9be1bb450e2bc192953178f33b90350..1eb4408eedc403d4d4fb0e273e9bd9d52ad88eeb 100644 (file)
@@ -138,7 +138,7 @@ pub fn inspect(&self) -> u64 { self.hash }
 /// We need to remove hashes of 0. That's reserved for empty buckets.
 /// This function wraps up `hash_keyed` to be the only way outside this
 /// module to generate a SafeHash.
-pub fn make_hash<Sized? T: Hash<S>, S, H: Hasher<S>>(hasher: &H, t: &T) -> SafeHash {
+pub fn make_hash<T: ?Sized + Hash<S>, S, H: Hasher<S>>(hasher: &H, t: &T) -> SafeHash {
     // We need to avoid 0u64 in order to prevent collisions with
     // EMPTY_HASH. We can maintain our precious uniform distribution
     // of initial indexes by unconditionally setting the MSB,
index c0445fb5aea97babd873ca904f8678e4c6dcd93e..ef9d28bbbb2e863bd993080831155ff454335613 100644 (file)
 //! }
 //! ```
 
-#![experimental]
+#![stable]
 
 pub use core_collections::{BinaryHeap, Bitv, BitvSet, BTreeMap, BTreeSet};
 pub use core_collections::{DList, RingBuf, VecMap};
 
 mod hash;
 
+#[stable]
 pub mod hash_map {
     //! A hashmap
     pub use super::hash::map::*;
 }
 
+#[stable]
 pub mod hash_set {
     //! A hashset
     pub use super::hash::set::*;
index de3d75ffb324202c49001b202a2eee40b852c4a1..2d013a8a5b830325c083a49e35c3ccfa0d1fd342 100644 (file)
@@ -17,7 +17,7 @@
 
 use prelude::v1::*;
 
-use c_str::ToCStr;
+use ffi::CString;
 use mem;
 use os;
 use str;
@@ -51,13 +51,11 @@ impl DynamicLibrary {
 
     /// Lazily open a dynamic library. When passed None it gives a
     /// handle to the calling process
-    pub fn open<T: ToCStr>(filename: Option<T>)
-                        -> Result<DynamicLibrary, String> {
+    pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
         unsafe {
-            let mut filename = filename;
             let maybe_library = dl::check_for_errors_in(|| {
-                match filename.take() {
-                    Some(name) => dl::open_external(name),
+                match filename {
+                    Some(name) => dl::open_external(name.as_vec()),
                     None => dl::open_internal()
                 }
             });
@@ -130,10 +128,9 @@ pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
         // This function should have a lifetime constraint of 'a on
         // T but that feature is still unimplemented
 
+        let raw_string = CString::from_slice(symbol.as_bytes());
         let maybe_symbol_value = dl::check_for_errors_in(|| {
-            symbol.with_c_str(|raw_string| {
-                dl::symbol(self.handle, raw_string)
-            })
+            dl::symbol(self.handle, raw_string.as_ptr())
         });
 
         // The value must not be constructed if there is an error so
@@ -157,7 +154,7 @@ mod test {
     fn test_loading_cosine() {
         // The math library does not need to be loaded since it is already
         // statically linked in
-        let none: Option<Path> = None; // appease the typechecker
+        let none: Option<&Path> = None; // appease the typechecker
         let libm = match DynamicLibrary::open(none) {
             Err(error) => panic!("Could not load self as module: {}", error),
             Ok(libm) => libm
@@ -202,17 +199,17 @@ fn test_errors_do_not_crash() {
           target_os = "freebsd",
           target_os = "dragonfly"))]
 pub mod dl {
-    use self::Rtld::*;
-
+    pub use self::Rtld::*;
     use prelude::v1::*;
-    use c_str::{CString, ToCStr};
+
+    use ffi::{self, CString};
+    use str;
     use libc;
     use ptr;
 
-    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *mut u8 {
-        filename.with_c_str(|raw_name| {
-            dlopen(raw_name, Lazy as libc::c_int) as *mut u8
-        })
+    pub unsafe fn open_external(filename: &[u8]) -> *mut u8 {
+        let s = CString::from_slice(filename);
+        dlopen(s.as_ptr(), Lazy as libc::c_int) as *mut u8
     }
 
     pub unsafe fn open_internal() -> *mut u8 {
@@ -236,8 +233,8 @@ pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
             let ret = if ptr::null() == last_error {
                 Ok(result)
             } else {
-                Err(String::from_str(CString::new(last_error, false).as_str()
-                    .unwrap()))
+                let s = ffi::c_str_to_bytes(&last_error);
+                Err(str::from_utf8(s).unwrap().to_string())
             };
 
             ret
@@ -273,7 +270,6 @@ fn dlsym(handle: *mut libc::c_void,
 
 #[cfg(target_os = "windows")]
 pub mod dl {
-    use c_str::ToCStr;
     use iter::IteratorExt;
     use libc;
     use ops::FnOnce;
@@ -287,10 +283,9 @@ pub mod dl {
     use string::String;
     use vec::Vec;
 
-    pub unsafe fn open_external<T: ToCStr>(filename: T) -> *mut u8 {
+    pub unsafe fn open_external(filename: &[u8]) -> *mut u8 {
         // Windows expects Unicode data
-        let filename_cstr = filename.to_c_str();
-        let filename_str = str::from_utf8(filename_cstr.as_bytes_no_nul()).unwrap();
+        let filename_str = str::from_utf8(filename).unwrap();
         let mut filename_str: Vec<u16> = filename_str.utf16_units().collect();
         filename_str.push(0);
         LoadLibraryW(filename_str.as_ptr() as *const libc::c_void) as *mut u8
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
new file mode 100644 (file)
index 0000000..bef2344
--- /dev/null
@@ -0,0 +1,218 @@
+// Copyright 2012 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.
+
+use fmt;
+use iter::IteratorExt;
+use libc;
+use mem;
+use ops::Deref;
+use slice::{self, SliceExt, AsSlice};
+use string::String;
+use vec::Vec;
+
+/// A type representing a C-compatible string
+///
+/// This type serves the primary purpose of being able to generate a
+/// C-compatible string from a Rust byte slice or vector. An instance of this
+/// type is a static guarantee that the underlying bytes contain no interior 0
+/// bytes and the final byte is 0.
+///
+/// A `CString` is created from either a byte slice or a byte vector. After
+/// being created, a `CString` predominately inherits all of its methods from
+/// the `Deref` implementation to `[libc::c_char]`. Note that the underlying
+/// array is represented as an array of `libc::c_char` as opposed to `u8`. A
+/// `u8` slice can be obtained with the `as_bytes` method.  Slices produced from
+/// a `CString` do *not* contain the trailing nul terminator unless otherwise
+/// specified.
+///
+/// # Example
+///
+/// ```no_run
+/// # extern crate libc;
+/// # fn main() {
+/// use std::ffi::CString;
+/// use libc;
+///
+/// extern {
+///     fn my_printer(s: *const libc::c_char);
+/// }
+///
+/// let to_print = "Hello, world!";
+/// let c_to_print = CString::from_slice(to_print.as_bytes());
+/// unsafe {
+///     my_printer(c_to_print.as_ptr());
+/// }
+/// # }
+/// ```
+#[derive(Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
+pub struct CString {
+    inner: Vec<libc::c_char>,
+}
+
+impl CString {
+    /// Create a new C-compatible string from a byte slice.
+    ///
+    /// This method will copy the data of the slice provided into a new
+    /// allocation, ensuring that there is a trailing 0 byte.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if there are any 0 bytes already in the slice
+    /// provided.
+    pub fn from_slice(v: &[u8]) -> CString {
+        CString::from_vec(v.to_vec())
+    }
+
+    /// Create a C-compatible string from a byte vector.
+    ///
+    /// This method will consume ownership of the provided vector, appending a 0
+    /// byte to the end after verifying that there are no interior 0 bytes.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if there are any 0 bytes already in the vector
+    /// provided.
+    pub fn from_vec(v: Vec<u8>) -> CString {
+        assert!(!v.iter().any(|&x| x == 0));
+        unsafe { CString::from_vec_unchecked(v) }
+    }
+
+    /// Create a C-compatibel string from a byte vector without checking for
+    /// interior 0 bytes.
+    ///
+    /// This method is equivalent to `from_vec` except that no runtime assertion
+    /// is made that `v` contains no 0 bytes.
+    pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
+        v.push(0);
+        CString { inner: mem::transmute(v) }
+    }
+
+    /// Create a view into this C string which includes the trailing nul
+    /// terminator at the end of the string.
+    pub fn as_slice_with_nul(&self) -> &[libc::c_char] { self.inner.as_slice() }
+
+    /// Similar to the `as_slice` method, but returns a `u8` slice instead of a
+    /// `libc::c_char` slice.
+    pub fn as_bytes(&self) -> &[u8] {
+        unsafe { mem::transmute(self.as_slice()) }
+    }
+
+    /// Equivalend to `as_slice_with_nul` except that the type returned is a
+    /// `u8` slice instead of a `libc::c_char` slice.
+    pub fn as_bytes_with_nul(&self) -> &[u8] {
+        unsafe { mem::transmute(self.as_slice_with_nul()) }
+    }
+}
+
+impl Deref for CString {
+    type Target = [libc::c_char];
+
+    fn deref(&self) -> &[libc::c_char] {
+        self.inner.slice_to(self.inner.len() - 1)
+    }
+}
+
+impl fmt::Show for CString {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        String::from_utf8_lossy(self.as_bytes()).fmt(f)
+    }
+}
+
+/// Interpret a C string as a byte slice.
+///
+/// This function will calculate the length of the C string provided, and it
+/// will then return a corresponding slice for the contents of the C string not
+/// including the nul terminator.
+///
+/// This function will tie the lifetime of the returned slice to the lifetime of
+/// the pointer provided. This is done to help prevent the slice from escaping
+/// the lifetime of the pointer itself. If a longer lifetime is needed, then
+/// `mem::copy_lifetime` should be used.
+///
+/// This function is unsafe because there is no guarantee of the validity of the
+/// pointer `raw` or a guarantee that a nul terminator will be found.
+///
+/// # Example
+///
+/// ```no_run
+/// # extern crate libc;
+/// # fn main() {
+/// use std::ffi;
+/// use std::str;
+/// use libc;
+///
+/// extern {
+///     fn my_string() -> *const libc::c_char;
+/// }
+///
+/// unsafe {
+///     let to_print = my_string();
+///     let slice = ffi::c_str_to_bytes(&to_print);
+///     println!("string returned: {}", str::from_utf8(slice).unwrap());
+/// }
+/// # }
+/// ```
+pub unsafe fn c_str_to_bytes<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
+    let len = libc::strlen(*raw);
+    slice::from_raw_buf(&*(raw as *const _ as *const *const u8), len as uint)
+}
+
+/// Interpret a C string as a byte slice with the nul terminator.
+///
+/// This function is identical to `from_raw_buf` except that the returned slice
+/// will include the nul terminator of the string.
+pub unsafe fn c_str_to_bytes_with_nul<'a>(raw: &'a *const libc::c_char) -> &'a [u8] {
+    let len = libc::strlen(*raw) + 1;
+    slice::from_raw_buf(&*(raw as *const _ as *const *const u8), len as uint)
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::v1::*;
+    use super::*;
+    use libc;
+    use mem;
+
+    #[test]
+    fn c_to_rust() {
+        let data = b"123\0";
+        let ptr = data.as_ptr() as *const libc::c_char;
+        unsafe {
+            assert_eq!(c_str_to_bytes(&ptr), b"123");
+            assert_eq!(c_str_to_bytes_with_nul(&ptr), b"123\0");
+        }
+    }
+
+    #[test]
+    fn simple() {
+        let s = CString::from_slice(b"1234");
+        assert_eq!(s.as_bytes(), b"1234");
+        assert_eq!(s.as_bytes_with_nul(), b"1234\0");
+        unsafe {
+            assert_eq!(s.as_slice(),
+                       mem::transmute::<_, &[libc::c_char]>(b"1234"));
+            assert_eq!(s.as_slice_with_nul(),
+                       mem::transmute::<_, &[libc::c_char]>(b"1234\0"));
+        }
+    }
+
+    #[should_fail] #[test]
+    fn build_with_zero1() { CString::from_slice(b"\0"); }
+    #[should_fail] #[test]
+    fn build_with_zero2() { CString::from_vec(vec![0]); }
+
+    #[test]
+    fn build_with_zero3() {
+        unsafe {
+            let s = CString::from_vec_unchecked(vec![0]);
+            assert_eq!(s.as_bytes(), b"\0");
+        }
+    }
+}
diff --git a/src/libstd/ffi/mod.rs b/src/libstd/ffi/mod.rs
new file mode 100644 (file)
index 0000000..cc86f80
--- /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.
+
+//! Utilities related to FFI bindings.
+
+#![unstable = "module just underwent fairly large reorganization and the dust \
+               still needs to settle"]
+
+pub use self::c_str::CString;
+pub use self::c_str::c_str_to_bytes;
+pub use self::c_str::c_str_to_bytes_with_nul;
+
+mod c_str;
index cdd0e9bf76f86dfa91f1ca536d80810b2c10ff31..ac2b01e995e2c62b5b17cea4e589659149bff133 100644 (file)
@@ -90,7 +90,7 @@ pub fn new() -> RandomSipHasher {
 
 impl Hasher<sip::SipState> for RandomSipHasher {
     #[inline]
-    fn hash<Sized? T: Hash<sip::SipState>>(&self, value: &T) -> u64 {
+    fn hash<T: ?Sized + Hash<sip::SipState>>(&self, value: &T) -> u64 {
         self.hasher.hash(value)
     }
 }
index c56acd38e810f2f89c380c58af5948ce4f02c4d0..d590aa8419453d6de9ce3ed35c62fba98b719052 100644 (file)
 
 use cmp;
 use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
-use iter::ExactSizeIterator;
+use iter::{IteratorExt, ExactSizeIterator};
 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 3fa0b5645c5288fba7b0ccc61a802ac7b20e88d8..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
@@ -1012,12 +1015,12 @@ fn flush(&mut self) -> IoResult<()> { Ok(()) }
     fn write_fmt(&mut self, fmt: fmt::Arguments) -> IoResult<()> {
         // Create a shim which translates a Writer to a fmt::Writer and saves
         // off I/O errors. instead of discarding them
-        struct Adaptor<'a, Sized? T:'a> {
+        struct Adaptor<'a, T: ?Sized +'a> {
             inner: &'a mut T,
             error: IoResult<()>,
         }
 
-        impl<'a, Sized? T: Writer> fmt::Writer for Adaptor<'a, T> {
+        impl<'a, T: ?Sized + Writer> fmt::Writer for Adaptor<'a, T> {
             fn write_str(&mut self, s: &str) -> fmt::Result {
                 match self.inner.write(s.as_bytes()) {
                     Ok(()) => Ok(()),
@@ -1597,11 +1600,11 @@ fn incoming<'r>(&'r mut self) -> IncomingConnections<'r, Self> {
 /// `Some`. The `Some` contains the `IoResult` representing whether the
 /// connection attempt was successful.  A successful connection will be wrapped
 /// in `Ok`. A failed connection is represented as an `Err`.
-pub struct IncomingConnections<'a, Sized? A:'a> {
+pub struct IncomingConnections<'a, A: ?Sized +'a> {
     inc: &'a mut A,
 }
 
-impl<'a, T, Sized? A: Acceptor<T>> Iterator for IncomingConnections<'a, A> {
+impl<'a, T, A: ?Sized + Acceptor<T>> Iterator for IncomingConnections<'a, A> {
     type Item = IoResult<T>;
 
     fn next(&mut self) -> Option<IoResult<T>> {
index daefdd28b306a5c7264154e567ea18ee28e6fccd..738c70412f78a0aa3def5993a313879ecdeed747 100644 (file)
@@ -22,7 +22,8 @@
 
 use prelude::v1::*;
 
-use c_str::ToCStr;
+use ffi::CString;
+use path::BytesContainer;
 use io::{Listener, Acceptor, IoResult, TimedOut, standard_error};
 use sys::pipe::UnixAcceptor as UnixAcceptorImp;
 use sys::pipe::UnixListener as UnixListenerImp;
@@ -53,8 +54,9 @@ impl UnixStream {
     /// let mut stream = UnixStream::connect(&server);
     /// stream.write(&[1, 2, 3]);
     /// ```
-    pub fn connect<P: ToCStr>(path: &P) -> IoResult<UnixStream> {
-        UnixStreamImp::connect(&path.to_c_str(), None)
+    pub fn connect<P: BytesContainer>(path: P) -> IoResult<UnixStream> {
+        let path = CString::from_slice(path.container_as_bytes());
+        UnixStreamImp::connect(&path, None)
             .map(|inner| UnixStream { inner: inner })
     }
 
@@ -67,13 +69,15 @@ pub fn connect<P: ToCStr>(path: &P) -> IoResult<UnixStream> {
     /// If a `timeout` with zero or negative duration is specified then
     /// the function returns `Err`, with the error kind set to `TimedOut`.
     #[experimental = "the timeout argument is likely to change types"]
-    pub fn connect_timeout<P: ToCStr>(path: &P,
-                                      timeout: Duration) -> IoResult<UnixStream> {
+    pub fn connect_timeout<P>(path: P, timeout: Duration)
+                              -> IoResult<UnixStream>
+                              where P: BytesContainer {
         if timeout <= Duration::milliseconds(0) {
             return Err(standard_error(TimedOut));
         }
 
-        UnixStreamImp::connect(&path.to_c_str(), Some(timeout.num_milliseconds() as u64))
+        let path = CString::from_slice(path.container_as_bytes());
+        UnixStreamImp::connect(&path, Some(timeout.num_milliseconds() as u64))
             .map(|inner| UnixStream { inner: inner })
     }
 
@@ -177,8 +181,9 @@ impl UnixListener {
     /// }
     /// # }
     /// ```
-    pub fn bind<P: ToCStr>(path: &P) -> IoResult<UnixListener> {
-        UnixListenerImp::bind(&path.to_c_str())
+    pub fn bind<P: BytesContainer>(path: P) -> IoResult<UnixListener> {
+        let path = CString::from_slice(path.container_as_bytes());
+        UnixListenerImp::bind(&path)
             .map(|inner| UnixListener { inner: inner })
     }
 }
index 5886c9cc3e287cce773223efc80ef48546860fb6..ea232ad0c3f1b0876b1d860fb1dd1447397b7d1f 100644 (file)
@@ -18,8 +18,8 @@
 
 use prelude::v1::*;
 
-use c_str::{CString, ToCStr};
 use collections::HashMap;
+use ffi::CString;
 use fmt;
 use hash::Hash;
 use io::pipe::{PipeStream, PipePair};
@@ -35,6 +35,7 @@
 use thread::Thread;
 
 #[cfg(windows)] use std::hash::sip::SipState;
+#[cfg(windows)] use str;
 
 /// Signal a process to exit, without forcibly killing it. Corresponds to
 /// SIGTERM on unix platforms.
@@ -109,11 +110,11 @@ pub struct Process {
 impl Hash for EnvKey {
     fn hash(&self, state: &mut SipState) {
         let &EnvKey(ref x) = self;
-        match x.as_str() {
-            Some(s) => for ch in s.chars() {
+        match str::from_utf8(x.as_bytes()) {
+            Ok(s) => for ch in s.chars() {
                 (ch as u8 as char).to_lowercase().hash(state);
             },
-            None => x.hash(state)
+            Err(..) => x.hash(state)
         }
     }
 }
@@ -123,8 +124,8 @@ impl PartialEq for EnvKey {
     fn eq(&self, other: &EnvKey) -> bool {
         let &EnvKey(ref x) = self;
         let &EnvKey(ref y) = other;
-        match (x.as_str(), y.as_str()) {
-            (Some(xs), Some(ys)) => {
+        match (str::from_utf8(x.as_bytes()), str::from_utf8(y.as_bytes())) {
+            (Ok(xs), Ok(ys)) => {
                 if xs.len() != ys.len() {
                     return false
                 } else {
@@ -185,10 +186,10 @@ pub struct Command {
 }
 
 // FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
-// we cannot usefully take ToCStr arguments by reference (without forcing an
+// we cannot usefully take BytesContainer arguments by reference (without forcing an
 // additional & around &str). So we are instead temporarily adding an instance
-// for &Path, so that we can take ToCStr as owned. When DST lands, the &Path
-// instance should be removed, and arguments bound by ToCStr should be passed by
+// for &Path, so that we can take BytesContainer as owned. When DST lands, the &Path
+// instance should be removed, and arguments bound by BytesContainer should be passed by
 // reference. (Here: {new, arg, args, env}.)
 
 impl Command {
@@ -203,9 +204,9 @@ impl Command {
     ///
     /// Builder methods are provided to change these defaults and
     /// otherwise configure the process.
-    pub fn new<T:ToCStr>(program: T) -> Command {
+    pub fn new<T: BytesContainer>(program: T) -> Command {
         Command {
-            program: program.to_c_str(),
+            program: CString::from_slice(program.container_as_bytes()),
             args: Vec::new(),
             env: None,
             cwd: None,
@@ -219,27 +220,29 @@ pub fn new<T:ToCStr>(program: T) -> Command {
     }
 
     /// Add an argument to pass to the program.
-    pub fn arg<'a, T: ToCStr>(&'a mut self, arg: T) -> &'a mut Command {
-        self.args.push(arg.to_c_str());
+    pub fn arg<'a, T: BytesContainer>(&'a mut self, arg: T) -> &'a mut Command {
+        self.args.push(CString::from_slice(arg.container_as_bytes()));
         self
     }
 
     /// Add multiple arguments to pass to the program.
-    pub fn args<'a, T: ToCStr>(&'a mut self, args: &[T]) -> &'a mut Command {
-        self.args.extend(args.iter().map(|arg| arg.to_c_str()));;
+    pub fn args<'a, T: BytesContainer>(&'a mut self, args: &[T]) -> &'a mut Command {
+        self.args.extend(args.iter().map(|arg| {
+            CString::from_slice(arg.container_as_bytes())
+        }));
         self
     }
     // Get a mutable borrow of the environment variable map for this `Command`.
-    fn get_env_map<'a>(&'a mut self) -> &'a mut  EnvMap {
+    fn get_env_map<'a>(&'a mut self) -> &'a mut EnvMap {
         match self.env {
             Some(ref mut map) => map,
             None => {
                 // if the env is currently just inheriting from the parent's,
                 // materialize the parent's env into a hashtable.
-                self.env = Some(os::env_as_bytes().into_iter()
-                                   .map(|(k, v)| (EnvKey(k.to_c_str()),
-                                                  v.to_c_str()))
-                                   .collect());
+                self.env = Some(os::env_as_bytes().into_iter().map(|(k, v)| {
+                    (EnvKey(CString::from_slice(k.as_slice())),
+                     CString::from_slice(v.as_slice()))
+                }).collect());
                 self.env.as_mut().unwrap()
             }
         }
@@ -249,15 +252,20 @@ fn get_env_map<'a>(&'a mut self) -> &'a mut  EnvMap {
     ///
     /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
     /// and case-sensitive on all other platforms.
-    pub fn env<'a, T: ToCStr, U: ToCStr>(&'a mut self, key: T, val: U)
-                                         -> &'a mut Command {
-        self.get_env_map().insert(EnvKey(key.to_c_str()), val.to_c_str());
+    pub fn env<'a, T, U>(&'a mut self, key: T, val: U)
+                         -> &'a mut Command
+                         where T: BytesContainer, U: BytesContainer {
+        let key = EnvKey(CString::from_slice(key.container_as_bytes()));
+        let val = CString::from_slice(val.container_as_bytes());
+        self.get_env_map().insert(key, val);
         self
     }
 
     /// Removes an environment variable mapping.
-    pub fn env_remove<'a, T: ToCStr>(&'a mut self, key: T) -> &'a mut Command {
-        self.get_env_map().remove(&EnvKey(key.to_c_str()));
+    pub fn env_remove<'a, T>(&'a mut self, key: T) -> &'a mut Command
+                             where T: BytesContainer {
+        let key = EnvKey(CString::from_slice(key.container_as_bytes()));
+        self.get_env_map().remove(&key);
         self
     }
 
@@ -265,16 +273,19 @@ pub fn env_remove<'a, T: ToCStr>(&'a mut self, key: T) -> &'a mut Command {
     ///
     /// If the given slice contains multiple instances of an environment
     /// variable, the *rightmost* instance will determine the value.
-    pub fn env_set_all<'a, T: ToCStr, U: ToCStr>(&'a mut self, env: &[(T,U)])
-                                                 -> &'a mut Command {
-        self.env = Some(env.iter().map(|&(ref k, ref v)| (EnvKey(k.to_c_str()), v.to_c_str()))
-                                  .collect());
+    pub fn env_set_all<'a, T, U>(&'a mut self, env: &[(T,U)])
+                                 -> &'a mut Command
+                                 where T: BytesContainer, U: BytesContainer {
+        self.env = Some(env.iter().map(|&(ref k, ref v)| {
+            (EnvKey(CString::from_slice(k.container_as_bytes())),
+             CString::from_slice(v.container_as_bytes()))
+        }).collect());
         self
     }
 
     /// Set the working directory for the child process.
     pub fn cwd<'a>(&'a mut self, dir: &Path) -> &'a mut Command {
-        self.cwd = Some(dir.to_c_str());
+        self.cwd = Some(CString::from_slice(dir.as_vec()));
         self
     }
 
@@ -389,9 +400,9 @@ impl fmt::Show for Command {
     /// non-utf8 data is lossily converted using the utf8 replacement
     /// character.
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "{}", String::from_utf8_lossy(self.program.as_bytes_no_nul())));
+        try!(write!(f, "{}", String::from_utf8_lossy(self.program.as_bytes())));
         for arg in self.args.iter() {
-            try!(write!(f, " '{}'", String::from_utf8_lossy(arg.as_bytes_no_nul())));
+            try!(write!(f, " '{}'", String::from_utf8_lossy(arg.as_bytes())));
         }
         Ok(())
     }
@@ -1208,13 +1219,13 @@ fn dont_close_fd_on_command_spawn() {
     #[test]
     #[cfg(windows)]
     fn env_map_keys_ci() {
-        use c_str::ToCStr;
+        use ffi::CString;
         use super::EnvKey;
         let mut cmd = Command::new("");
         cmd.env("path", "foo");
         cmd.env("Path", "bar");
         let env = &cmd.env.unwrap();
-        let val = env.get(&EnvKey("PATH".to_c_str()));
-        assert!(val.unwrap() == &"bar".to_c_str());
+        let val = env.get(&EnvKey(CString::from_slice(b"PATH")));
+        assert!(val.unwrap() == &CString::from_slice(b"bar"));
     }
 }
index 45e0dd4e8e5dfd7fa5871871a59e21dd89c39f85..394686be814f24c593ce5c72080c6164c1fbc6be 100644 (file)
 
 //! Temporary files and directories
 
-use io::{fs, IoResult};
+use io::{fs, IoError, IoErrorKind, IoResult};
 use io;
-use libc;
+use iter::{IteratorExt, range};
 use ops::Drop;
 use option::Option;
 use option::Option::{None, Some};
 use os;
 use path::{Path, GenericPath};
+use rand::{Rng, thread_rng};
 use result::Result::{Ok, Err};
-use sync::atomic::{AtomicUint, ATOMIC_UINT_INIT, Ordering};
+use str::StrExt;
+use string::String;
 
 /// A wrapper for a path to temporary directory implementing automatic
 /// scope-based deletion.
@@ -31,7 +33,7 @@
 ///
 /// {
 ///     // create a temporary directory
-///     let tmpdir = match TempDir::new("mysuffix") {
+///     let tmpdir = match TempDir::new("myprefix") {
 ///         Ok(dir) => dir,
 ///         Err(e) => panic!("couldn't create temporary directory: {}", e)
 ///     };
@@ -46,7 +48,7 @@
 /// }
 /// {
 ///     // create a temporary directory, this time using a custom path
-///     let tmpdir = match TempDir::new_in(&Path::new("/tmp/best/custom/path"), "mysuffix") {
+///     let tmpdir = match TempDir::new_in(&Path::new("/tmp/best/custom/path"), "myprefix") {
 ///         Ok(dir) => dir,
 ///         Err(e) => panic!("couldn't create temporary directory: {}", e)
 ///     };
@@ -61,7 +63,7 @@
 /// }
 /// {
 ///     // create a temporary directory
-///     let tmpdir = match TempDir::new("mysuffix") {
+///     let tmpdir = match TempDir::new("myprefix") {
 ///         Ok(dir) => dir,
 ///         Err(e) => panic!("couldn't create temporary directory: {}", e)
 ///     };
@@ -78,47 +80,59 @@ pub struct TempDir {
     disarmed: bool
 }
 
+// How many times should we (re)try finding an unused random name? It should be
+// enough that an attacker will run out of luck before we run out of patience.
+const NUM_RETRIES: u32 = 1 << 31;
+// How many characters should we include in a random file name? It needs to
+// be enough to dissuade an attacker from trying to preemptively create names
+// of that length, but not so huge that we unnecessarily drain the random number
+// generator of entropy.
+const NUM_RAND_CHARS: uint = 12;
+
 impl TempDir {
     /// Attempts to make a temporary directory inside of `tmpdir` whose name
-    /// will have the suffix `suffix`. The directory will be automatically
+    /// will have the prefix `prefix`. The directory will be automatically
     /// deleted once the returned wrapper is destroyed.
     ///
     /// If no directory can be created, `Err` is returned.
-    pub fn new_in(tmpdir: &Path, suffix: &str) -> IoResult<TempDir> {
+    pub fn new_in(tmpdir: &Path, prefix: &str) -> IoResult<TempDir> {
         if !tmpdir.is_absolute() {
             let abs_tmpdir = try!(os::make_absolute(tmpdir));
-            return TempDir::new_in(&abs_tmpdir, suffix);
+            return TempDir::new_in(&abs_tmpdir, prefix);
         }
 
-        static CNT: AtomicUint = ATOMIC_UINT_INIT;
-
-        let mut attempts = 0u;
-        loop {
-            let filename =
-                format!("rs-{}-{}-{}",
-                        unsafe { libc::getpid() },
-                        CNT.fetch_add(1, Ordering::SeqCst),
-                        suffix);
-            let p = tmpdir.join(filename);
-            match fs::mkdir(&p, io::USER_RWX) {
-                Err(error) => {
-                    if attempts >= 1000 {
-                        return Err(error)
-                    }
-                    attempts += 1;
-                }
-                Ok(()) => return Ok(TempDir { path: Some(p), disarmed: false })
+        let mut rng = thread_rng();
+        for _ in range(0, NUM_RETRIES) {
+            let suffix: String = rng.gen_ascii_chars().take(NUM_RAND_CHARS).collect();
+            let leaf = if prefix.len() > 0 {
+                format!("{}.{}", prefix, suffix)
+            } else {
+                // If we're given an empty string for a prefix, then creating a
+                // directory starting with "." would lead to it being
+                // semi-invisible on some systems.
+                suffix
+            };
+            let path = tmpdir.join(leaf);
+            match fs::mkdir(&path, io::USER_RWX) {
+                Ok(_) => return Ok(TempDir { path: Some(path), disarmed: false }),
+                Err(IoError{kind:IoErrorKind::PathAlreadyExists,..}) => (),
+                Err(e) => return Err(e)
             }
         }
+
+        return Err(IoError{
+                       kind: IoErrorKind::PathAlreadyExists,
+                       desc:"Exhausted",
+                       detail: None});
     }
 
     /// Attempts to make a temporary directory inside of `os::tmpdir()` whose
-    /// name will have the suffix `suffix`. The directory will be automatically
+    /// name will have the prefix `prefix`. The directory will be automatically
     /// deleted once the returned wrapper is destroyed.
     ///
     /// If no directory can be created, `Err` is returned.
-    pub fn new(suffix: &str) -> IoResult<TempDir> {
-        TempDir::new_in(&os::tmpdir(), suffix)
+    pub fn new(prefix: &str) -> IoResult<TempDir> {
+        TempDir::new_in(&os::tmpdir(), prefix)
     }
 
     /// Unwrap the wrapped `std::path::Path` from the `TempDir` wrapper.
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 608ad9882b97719fe487fdcd08b510d49fb82c73..b9f226c5aca73e83a227f4fc81b1116bc4cf5a0d 100644 (file)
@@ -95,7 +95,7 @@
 //! and `format!`, also available to all Rust code.
 
 #![crate_name = "std"]
-#![unstable]
+#![stable]
 #![crate_type = "rlib"]
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
 
 #![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;
 
 /* Runtime and platform support */
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 pub mod thread_local;
-pub mod c_str;
-pub mod c_vec;
+
 pub mod dynamic_lib;
+pub mod ffi;
 pub mod fmt;
 pub mod io;
 pub mod os;
index 63fd3209cc0193b619f811373be8f97886f57781..d96441e09a813efa82ee5c66384c11074d90416c 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 be8f82349c2224496729c0adb2060dc888ff5a35..300ceec4b45bf3a047a54a0947a29395cd8accc3 100644 (file)
 use sync::atomic::{AtomicInt, ATOMIC_INT_INIT, Ordering};
 use vec::Vec;
 
-#[cfg(unix)] use c_str::ToCStr;
+#[cfg(unix)] use ffi::{self, CString};
 
-#[cfg(unix)]
-pub use sys::ext as unix;
-#[cfg(windows)]
-pub use sys::ext as windows;
+#[cfg(unix)] pub use sys::ext as unix;
+#[cfg(windows)] pub use sys::ext as windows;
 
 /// Get the number of cores available
 pub fn num_cpus() -> uint {
@@ -196,15 +194,14 @@ pub fn getenv(n: &str) -> Option<String> {
 ///
 /// Panics if `n` has any interior NULs.
 pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
-    use c_str::CString;
-
     unsafe {
         with_env_lock(|| {
-            let s = n.with_c_str(|buf| libc::getenv(buf));
+            let s = CString::from_slice(n.as_bytes());
+            let s = libc::getenv(s.as_ptr()) as *const _;
             if s.is_null() {
                 None
             } else {
-                Some(CString::new(s as *const libc::c_char, false).as_bytes_no_nul().to_vec())
+                Some(ffi::c_str_to_bytes(&s).to_vec())
             }
         })
     }
@@ -253,13 +250,12 @@ pub fn setenv<T: BytesContainer>(n: &str, v: T) {
     fn _setenv(n: &str, v: &[u8]) {
         unsafe {
             with_env_lock(|| {
-                n.with_c_str(|nbuf| {
-                    v.with_c_str(|vbuf| {
-                        if libc::funcs::posix01::unistd::setenv(nbuf, vbuf, 1) != 0 {
-                            panic!(IoError::last_error());
-                        }
-                    })
-                })
+                let k = CString::from_slice(n.as_bytes());
+                let v = CString::from_slice(v);
+                if libc::funcs::posix01::unistd::setenv(k.as_ptr(),
+                                                        v.as_ptr(), 1) != 0 {
+                    panic!(IoError::last_error());
+                }
             })
         }
     }
@@ -289,11 +285,10 @@ pub fn unsetenv(n: &str) {
     fn _unsetenv(n: &str) {
         unsafe {
             with_env_lock(|| {
-                n.with_c_str(|nbuf| {
-                    if libc::funcs::posix01::unistd::unsetenv(nbuf) != 0 {
-                        panic!(IoError::last_error());
-                    }
-                })
+                let nbuf = CString::from_slice(n.as_bytes());
+                if libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr()) != 0 {
+                    panic!(IoError::last_error());
+                }
             })
         }
     }
@@ -618,11 +613,10 @@ pub fn get_exit_status() -> int {
 #[cfg(target_os = "macos")]
 unsafe fn load_argc_and_argv(argc: int,
                              argv: *const *const c_char) -> Vec<Vec<u8>> {
-    use c_str::CString;
     use iter::range;
 
     range(0, argc as uint).map(|i| {
-        CString::new(*argv.offset(i as int), false).as_bytes_no_nul().to_vec()
+        ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec()
     }).collect()
 }
 
@@ -652,7 +646,6 @@ fn real_args_as_bytes() -> Vec<Vec<u8>> {
 // res
 #[cfg(target_os = "ios")]
 fn real_args_as_bytes() -> Vec<Vec<u8>> {
-    use c_str::CString;
     use iter::range;
     use mem;
 
index bf9ffbffe7d508b1f26bd331875b71493222943c..b020164158cff2d5d2e876b58403cc3016b7d244 100644 (file)
@@ -62,7 +62,7 @@
 #![experimental]
 
 use core::kinds::Sized;
-use c_str::CString;
+use ffi::CString;
 use clone::Clone;
 use fmt;
 use iter::IteratorExt;
@@ -786,7 +786,7 @@ fn is_relative(&self) -> bool {
 }
 
 /// A trait that represents something bytes-like (e.g. a &[u8] or a &str)
-pub trait BytesContainer for Sized? {
+pub trait BytesContainer {
     /// Returns a &[u8] representing the receiver
     fn container_as_bytes<'a>(&'a self) -> &'a [u8];
     /// Returns the receiver interpreted as a utf-8 string, if possible
@@ -892,11 +892,11 @@ fn container_as_bytes(&self) -> &[u8] {
 impl BytesContainer for CString {
     #[inline]
     fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
-        self.as_bytes_no_nul()
+        self.as_bytes()
     }
 }
 
-impl<'a, Sized? T: BytesContainer> BytesContainer for &'a T {
+impl<'a, T: ?Sized + BytesContainer> BytesContainer for &'a T {
     #[inline]
     fn container_as_bytes(&self) -> &[u8] {
         (**self).container_as_bytes()
@@ -913,21 +913,3 @@ fn is_str(_: Option<& &'a T>) -> bool { BytesContainer::is_str(None::<&T>) }
 fn contains_nul<T: BytesContainer>(v: &T) -> bool {
     v.container_as_bytes().iter().any(|&x| x == 0)
 }
-
-#[cfg(test)]
-mod tests {
-    use prelude::v1::*;
-    use c_str::ToCStr;
-    use path::{WindowsPath, PosixPath};
-
-    #[test]
-    fn test_cstring() {
-        let input = "/foo/bar/baz";
-        let path: PosixPath = PosixPath::new(input.to_c_str());
-        assert_eq!(path.as_vec(), input.as_bytes());
-
-        let input = r"\foo\bar\baz";
-        let path: WindowsPath = WindowsPath::new(input.to_c_str());
-        assert_eq!(path.as_str().unwrap(), input);
-    }
-}
index ae82e201cb8555793b4f33efd2366c98fecfad5e..d9981ace0301ec52b40ae8453951b392fe99df2d 100644 (file)
 
 //! POSIX file path handling
 
-use c_str::{CString, ToCStr};
 use clone::Clone;
-use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
+use cmp::{Ordering, Eq, Ord, PartialEq, PartialOrd};
 use hash;
 use io::Writer;
 use iter::{AdditiveIterator, Extend};
 use iter::{Iterator, IteratorExt, Map};
-use option::Option;
-use option::Option::{None, Some};
 use kinds::Sized;
-use str::{FromStr, Str};
-use str;
-use slice::{Split, AsSlice, SliceConcatExt, SliceExt};
+use option::Option::{self, Some, None};
+use slice::{AsSlice, Split, SliceExt, SliceConcatExt};
+use str::{self, FromStr, StrExt};
 use vec::Vec;
 
 use super::{BytesContainer, GenericPath, GenericPathUnsafe};
@@ -86,26 +83,6 @@ fn from_str(s: &str) -> Option<Path> {
     }
 }
 
-// FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
-// we cannot usefully take ToCStr arguments by reference (without forcing an
-// additional & around &str). So we are instead temporarily adding an instance
-// for &Path, so that we can take ToCStr as owned. When DST lands, the &Path
-// instance should be removed, and arguments bound by ToCStr should be passed by
-// reference.
-
-impl ToCStr for Path {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        // The Path impl guarantees no internal NUL
-        unsafe { self.to_c_str_unchecked() }
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        self.as_vec().to_c_str_unchecked()
-    }
-}
-
 impl<S: hash::Writer> hash::Hash<S> for Path {
     #[inline]
     fn hash(&self, state: &mut S) {
@@ -344,7 +321,7 @@ pub fn new_opt<T: BytesContainer>(path: T) -> Option<Path> {
 
     /// Returns a normalized byte vector representation of a path, by removing all empty
     /// components, and unnecessary . and .. components.
-    fn normalize<Sized? V: AsSlice<u8>>(v: &V) -> Vec<u8> {
+    fn normalize<V: ?Sized + AsSlice<u8>>(v: &V) -> Vec<u8> {
         // borrowck is being very picky
         let val = {
             let is_abs = !v.as_slice().is_empty() && v.as_slice()[0] == SEP_BYTE;
@@ -558,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);
@@ -573,7 +550,7 @@ macro_rules! t(
                     assert!(mo.as_slice() == $exp);
                 }
             )
-        );
+        }
 
         t!("foo", "foo");
         t!(b"foo\x80", "foo\u{FFFD}");
@@ -585,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);
@@ -595,7 +572,7 @@ macro_rules! t(
                     assert!(f == $expf);
                 }
             )
-        );
+        }
 
         t!(b"foo", "foo", "foo");
         t!(b"foo/bar", "foo/bar", "bar");
@@ -608,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);
@@ -629,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"));
@@ -692,7 +669,7 @@ macro_rules! t(
 
     #[test]
     fn test_push() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $join:expr) => (
                 {
                     let path = $path;
@@ -703,7 +680,7 @@ macro_rules! t(
                     assert!(p1 == p2.join(join));
                 }
             )
-        );
+        }
 
         t!(s: "a/b/c", "..");
         t!(s: "/a/b/c", "d");
@@ -713,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);
@@ -722,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");
@@ -734,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);
@@ -749,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");
@@ -762,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);
@@ -779,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);
@@ -818,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);
@@ -827,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");
@@ -839,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);
@@ -854,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");
@@ -917,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;
@@ -938,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");
@@ -961,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;
@@ -992,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);
@@ -1031,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);
@@ -1039,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);
@@ -1052,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);
@@ -1060,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);
@@ -1086,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);
@@ -1101,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);
@@ -1125,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);
@@ -1134,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"));
@@ -1170,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);
@@ -1196,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"]);
@@ -1216,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);
@@ -1228,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 cf8bc0e6242b312752e0ac621563ead9f994d2a5..4b5d793355b60137fabd2b321f25efb458076cb0 100644 (file)
 use self::PathPrefix::*;
 
 use ascii::AsciiExt;
-use c_str::{CString, ToCStr};
 use char::CharExt;
 use clone::Clone;
-use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
+use cmp::{Ordering, Eq, Ord, PartialEq, PartialOrd};
 use hash;
 use io::Writer;
 use iter::{AdditiveIterator, Extend};
 use iter::{Iterator, IteratorExt, Map, repeat};
 use mem;
-use option::Option;
-use option::Option::{Some, None};
+use option::Option::{self, Some, None};
 use slice::{SliceExt, SliceConcatExt};
 use str::{SplitTerminator, FromStr, StrExt};
 use string::{String, ToString};
@@ -112,26 +110,6 @@ fn from_str(s: &str) -> Option<Path> {
     }
 }
 
-// FIXME (#12938): Until DST lands, we cannot decompose &str into & and str, so
-// we cannot usefully take ToCStr arguments by reference (without forcing an
-// additional & around &str). So we are instead temporarily adding an instance
-// for &Path, so that we can take ToCStr as owned. When DST lands, the &Path
-// instance should be removed, and arguments bound by ToCStr should be passed by
-// reference.
-
-impl ToCStr for Path {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        // The Path impl guarantees no internal NUL
-        unsafe { self.to_c_str_unchecked() }
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        self.as_vec().to_c_str_unchecked()
-    }
-}
-
 impl<S: hash::Writer> hash::Hash<S> for Path {
     #[cfg(not(test))]
     #[inline]
@@ -1149,7 +1127,7 @@ macro_rules! t {
 
     #[test]
     fn test_parse_prefix() {
-        macro_rules! t(
+        macro_rules! t {
             ($path:expr, $exp:expr) => (
                 {
                     let path = $path;
@@ -1159,7 +1137,7 @@ macro_rules! t(
                             "parse_prefix(\"{}\"): expected {}, found {}", path, exp, res);
                 }
             )
-        );
+        }
 
         t!("\\\\SERVER\\share\\foo", Some(UNCPrefix(6,5)));
         t!("\\\\", None);
@@ -1348,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);
@@ -1358,7 +1336,7 @@ macro_rules! t(
                     assert_eq!(f, $expf);
                 }
             )
-        );
+        }
 
         t!("foo", "foo", "foo");
         t!("foo\\bar", "foo\\bar", "bar");
@@ -1367,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;
@@ -1390,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");
@@ -1490,7 +1468,7 @@ macro_rules! t(
 
     #[test]
     fn test_push() {
-        macro_rules! t(
+        macro_rules! t {
             (s: $path:expr, $join:expr) => (
                 {
                     let path = $path;
@@ -1501,7 +1479,7 @@ macro_rules! t(
                     assert!(p1 == p2.join(join));
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", "..");
         t!(s: "\\a\\b\\c", "d");
@@ -1525,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);
@@ -1534,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");
@@ -1577,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);
@@ -1592,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");
@@ -1606,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;
@@ -1627,7 +1605,7 @@ macro_rules! t(
                     assert!(result == $right);
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", "a\\b", true);
         t!(s: "a", ".", true);
@@ -1695,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);
@@ -1704,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");
@@ -1718,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);
@@ -1733,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");
@@ -1746,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;
@@ -1759,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");
@@ -1831,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;
@@ -1852,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");
@@ -1876,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;
@@ -1907,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);
@@ -1942,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);
@@ -1961,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);
@@ -1982,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);
@@ -1994,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);
@@ -2085,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);
@@ -2093,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);
@@ -2117,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);
@@ -2130,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"));
@@ -2251,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);
@@ -2265,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"]);
@@ -2309,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);
@@ -2321,7 +2299,7 @@ macro_rules! t(
                     assert_eq!(comps, exp);
                 }
             )
-        );
+        }
 
         t!(s: "a\\b\\c", [b"a", b"b", b"c"]);
         t!(s: ".", [b"."]);
@@ -2330,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);
@@ -2339,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 1fbd17ede08f2f70a5630b72ba815f48a82c5836..0496944dbaf88e081424a09fe7514099bcca4381 100644 (file)
@@ -35,5 +35,7 @@
 //! pervasive that it would be obnoxious to import for every use, particularly
 //! those that define methods on primitive types.
 
+#![stable]
+
 #[stable]
 pub mod v1;
index f6bdcd53dff24c29dd68528d1f45ebbb427e051f..9e9a483e1a5e3f510922eb6ae9b652eda2848162 100644 (file)
 #[stable] #[doc(no_inline)] pub use char::CharExt;
 #[stable] #[doc(no_inline)] pub use clone::Clone;
 #[stable] #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
-#[stable] #[doc(no_inline)] pub use iter::CloneIteratorExt;
 #[stable] #[doc(no_inline)] pub use iter::DoubleEndedIterator;
 #[stable] #[doc(no_inline)] pub use iter::ExactSizeIterator;
 #[stable] #[doc(no_inline)] pub use iter::{Iterator, IteratorExt, Extend};
-#[stable] #[doc(no_inline)] pub use iter::{IteratorCloneExt, IteratorOrdExt};
 #[stable] #[doc(no_inline)] pub use option::Option::{self, Some, None};
 #[stable] #[doc(no_inline)] pub use ptr::{PtrExt, MutPtrExt};
 #[stable] #[doc(no_inline)] pub use result::Result::{self, Ok, Err};
index aa28c8266d193ff059562f9c7509b933ee454c92..8855a7e5293ac18a04566cfc05cfccef1c6761f9 100644 (file)
 
 /// The standard RNG. This is designed to be efficient on the current
 /// platform.
-#[derive(Copy)]
+#[derive(Copy, Clone)]
 pub struct StdRng {
     rng: IsaacWordRng,
 }
@@ -322,6 +322,7 @@ fn reseed(&mut self, rng: &mut StdRng) {
 type ThreadRngInner = reseeding::ReseedingRng<StdRng, ThreadRngReseeder>;
 
 /// The thread-local RNG.
+#[derive(Clone)]
 pub struct ThreadRng {
     rng: Rc<RefCell<ThreadRngInner>>,
 }
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 4734a39c8354257a6fa21ed236160c8f42b964e5..86abacb936501f63124755cd6baeef981c9c7474 100644 (file)
@@ -46,8 +46,9 @@ pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
 mod imp {
     use prelude::v1::*;
 
+    use libc;
     use mem;
-    use slice;
+    use ffi;
 
     use sync::{StaticMutex, MUTEX_INIT};
 
@@ -95,13 +96,9 @@ fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
     }
 
     unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec<Vec<u8>> {
+        let argv = argv as *const *const libc::c_char;
         range(0, argc as uint).map(|i| {
-            let arg = *argv.offset(i as int);
-            let mut len = 0u;
-            while *arg.offset(len as int) != 0 {
-                len += 1u;
-            }
-            slice::from_raw_buf(&arg, len).to_vec()
+            ffi::c_str_to_bytes(&*argv.offset(i as int)).to_vec()
         }).collect()
     }
 
index 578239c9cc42ee7237980ca00a840d6888e28414..bb0b6fe804bea4e676c0520cee80d4539c8b95e6 100644 (file)
@@ -15,7 +15,7 @@
 use prelude::v1::*;
 
 use os;
-use sync::atomic::{mod, Ordering};
+use sync::atomic::{self, Ordering};
 
 pub use sys::backtrace::write;
 
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 a48a8edd82f60224e86a8cb53e14976c1ca069ae..71169386c186aee9400b363232787cf25c4a64af 100644 (file)
@@ -67,7 +67,7 @@
 use intrinsics;
 use libc::c_void;
 use mem;
-use sync::atomic::{mod, Ordering};
+use sync::atomic::{self, Ordering};
 use sync::{Once, ONCE_INIT};
 
 use rt::libunwind as uw;
index 883a01fa31801bebb237d1c6de79b64a6c32ff13..bc01ce926f8bc4306c43732cfdc51f8a546506af 100644 (file)
@@ -19,7 +19,7 @@
 use os;
 use slice;
 use str;
-use sync::atomic::{mod, Ordering};
+use sync::atomic::{self, Ordering};
 
 /// Dynamically inquire about whether we're running under V.
 /// You should usually not use this unless your test definitely
index 7734f655ed2936c5f1cc3be2f646e906ca7b97a6..e97be51fdbc25af6ccc56aec377ee00aee43173a 100644 (file)
@@ -188,6 +188,7 @@ pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
     pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
 }
 
+#[stable]
 impl Drop for Condvar {
     fn drop(&mut self) {
         unsafe { self.inner.inner.destroy() }
index 6ce278726e9deac24598f0a9020bbefd99c05dd7..6fff6765bd34879c3e9d246de2b00c034fe6fec9 100644 (file)
 //! and/or blocking at all, but rather provide the necessary tools to build
 //! other types of concurrent primitives.
 
-#![experimental]
+#![stable]
 
 pub use alloc::arc::{Arc, Weak};
 pub use core::atomic;
 
 pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
 pub use self::mutex::MUTEX_INIT;
-pub use self::rwlock::{RWLock, StaticRWLock, RWLOCK_INIT};
-pub use self::rwlock::{RWLockReadGuard, RWLockWriteGuard};
+pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
+pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
 pub use self::condvar::{Condvar, StaticCondvar, CONDVAR_INIT};
 pub use self::once::{Once, ONCE_INIT};
 pub use self::semaphore::{Semaphore, SemaphoreGuard};
index 6bc3f561bb3c74a967316e06815507bf8413d874..7c18b8a43faad827cbff96a4f577e61d2b8fc19a 100644 (file)
 //! }
 //! ```
 
+#![stable]
+
 // A description of how Rust's channel implementation works
 //
 // Channels are supposed to be the basic building block for all other
@@ -565,6 +567,7 @@ fn new(inner: Flavor<T>) -> Sender<T> {
     /// drop(rx);
     /// assert_eq!(tx.send(1i).err().unwrap().0, 1);
     /// ```
+    #[stable]
     pub fn send(&self, t: T) -> Result<(), SendError<T>> {
         let (new_inner, ret) = match *unsafe { self.inner() } {
             Flavor::Oneshot(ref p) => {
@@ -587,7 +590,7 @@ pub fn send(&self, t: T) -> Result<(), SendError<T>> {
                                 // asleep (we're looking at it), so the receiver
                                 // can't go away.
                                 (*a.get()).send(t).ok().unwrap();
-                                token.signal();
+                        token.signal();
                                 (a, Ok(()))
                             }
                         }
@@ -657,6 +660,7 @@ fn clone(&self) -> Sender<T> {
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<T: Send> Drop for Sender<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
@@ -720,6 +724,7 @@ fn clone(&self) -> SyncSender<T> {
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<T: Send> Drop for SyncSender<T> {
     fn drop(&mut self) {
         unsafe { (*self.inner.get()).drop_chan(); }
@@ -935,7 +940,7 @@ fn abort_selection(&self) -> bool {
     }
 }
 
-#[unstable]
+#[stable]
 impl<'a, T: Send> Iterator for Iter<'a, T> {
     type Item = T;
 
@@ -943,6 +948,7 @@ fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<T: Send> Drop for Receiver<T> {
     fn drop(&mut self) {
         match *unsafe { self.inner_mut() } {
index 8f85dc6e043e20de7bc859204ece37fac4f5553b..9ad24a5a11ec5dfb61080a507b4d4a61920a8198 100644 (file)
@@ -138,6 +138,7 @@ pub fn pop(&self) -> PopResult<T> {
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<T: Send> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
index b158bd69c7b506addc9ecd1df5fdf4d8e82a58ea..6b3dd89f33b07fcc71cc4a4a02cdfd7c4072ec2a 100644 (file)
@@ -228,6 +228,7 @@ pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<T: Send> Drop for Mutex<T> {
     fn drop(&mut self) {
         // This is actually safe b/c we know that there is no further usage of
@@ -291,6 +292,7 @@ fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
     }
 }
 
+#[stable]
 impl<'mutex, T> Deref for MutexGuard<'mutex, T> {
     type Target = T;
 
@@ -298,6 +300,7 @@ fn deref<'a>(&'a self) -> &'a T {
         unsafe { &*self.__data.get() }
     }
 }
+#[stable]
 impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> {
     fn deref_mut<'a>(&'a mut self) -> &'a mut T {
         unsafe { &mut *self.__data.get() }
@@ -305,6 +308,7 @@ fn deref_mut<'a>(&'a mut self) -> &'a mut T {
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<'a, T> Drop for MutexGuard<'a, T> {
     #[inline]
     fn drop(&mut self) {
index 08e323c9cb4c3da2e45fcfcebef7c64e20c0c84e..aa2d957a3eb5e14bb3268b2e539fcc51e31ff939 100644 (file)
@@ -121,10 +121,6 @@ pub fn call_once<F>(&'static self, f: F) where F: FnOnce() {
             unsafe { self.mutex.destroy() }
         }
     }
-
-    /// Deprecated
-    #[deprecated = "renamed to `call_once`"]
-    pub fn doit<F>(&'static self, f: F) where F: FnOnce() { self.call_once(f) }
 }
 
 #[cfg(test)]
index 6e4df1182091febb789c66a67f2564719701c8fc..385df45b400c41a8cebfeab79d47c92ac6c5aed5 100644 (file)
@@ -49,7 +49,7 @@ pub struct Guard {
 
 /// A type of error which can be returned whenever a lock is acquired.
 ///
-/// Both Mutexes and RWLocks are poisoned whenever a task fails while the lock
+/// Both Mutexes and RwLocks are poisoned whenever a task fails while the lock
 /// is held. The precise semantics for when a lock is poisoned is documented on
 /// each lock, but once a lock is poisoned then all future acquisitions will
 /// return this error.
index b2367ff8352fbb8d30f62b7f59080b93eb3bd9cb..4afd5bb63f4fec79c368880afcd2b433d23d0d48 100644 (file)
 ///
 /// # Poisoning
 ///
-/// RWLocks, like Mutexes, will become poisoned on panics. Note, however, that
-/// an RWLock may only be poisoned if a panic occurs while it is locked
+/// RwLocks, like Mutexes, will become poisoned on panics. Note, however, that
+/// an RwLock may only be poisoned if a panic occurs while it is locked
 /// exclusively (write mode). If a panic occurs in any reader, then the lock
 /// will not be poisoned.
 ///
 /// # Examples
 ///
 /// ```
-/// use std::sync::RWLock;
+/// use std::sync::RwLock;
 ///
-/// let lock = RWLock::new(5i);
+/// let lock = RwLock::new(5i);
 ///
 /// // many reader locks can be held at once
 /// {
 /// } // write lock is dropped here
 /// ```
 #[stable]
-pub struct RWLock<T> {
-    inner: Box<StaticRWLock>,
+pub struct RwLock<T> {
+    inner: Box<StaticRwLock>,
     data: UnsafeCell<T>,
 }
 
-unsafe impl<T:'static+Send> Send for RWLock<T> {}
-unsafe impl<T> Sync for RWLock<T> {}
+unsafe impl<T:'static+Send> Send for RwLock<T> {}
+unsafe impl<T> Sync for RwLock<T> {}
 
-/// Structure representing a statically allocated RWLock.
+/// Structure representing a statically allocated RwLock.
 ///
 /// This structure is intended to be used inside of a `static` and will provide
 /// automatic global access as well as lazy initialization. The internal
-/// resources of this RWLock, however, must be manually deallocated.
+/// resources of this RwLock, however, must be manually deallocated.
 ///
 /// # Example
 ///
 /// ```
-/// use std::sync::{StaticRWLock, RWLOCK_INIT};
+/// use std::sync::{StaticRwLock, RW_LOCK_INIT};
 ///
-/// static LOCK: StaticRWLock = RWLOCK_INIT;
+/// static LOCK: StaticRwLock = RW_LOCK_INIT;
 ///
 /// {
 ///     let _g = LOCK.read().unwrap();
@@ -90,18 +90,18 @@ unsafe impl<T> Sync for RWLock<T> {}
 /// }
 /// unsafe { LOCK.destroy() } // free all resources
 /// ```
-#[unstable = "may be merged with RWLock in the future"]
-pub struct StaticRWLock {
+#[unstable = "may be merged with RwLock in the future"]
+pub struct StaticRwLock {
     lock: sys::RWLock,
     poison: poison::Flag,
 }
 
-unsafe impl Send for StaticRWLock {}
-unsafe impl Sync for StaticRWLock {}
+unsafe impl Send for StaticRwLock {}
+unsafe impl Sync for StaticRwLock {}
 
 /// Constant initialization for a statically-initialized rwlock.
-#[unstable = "may be merged with RWLock in the future"]
-pub const RWLOCK_INIT: StaticRWLock = StaticRWLock {
+#[unstable = "may be merged with RwLock in the future"]
+pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock {
     lock: sys::RWLOCK_INIT,
     poison: poison::FLAG_INIT,
 };
@@ -110,8 +110,8 @@ unsafe impl Sync for StaticRWLock {}
 /// dropped.
 #[must_use]
 #[stable]
-pub struct RWLockReadGuard<'a, T: 'a> {
-    __lock: &'a StaticRWLock,
+pub struct RwLockReadGuard<'a, T: 'a> {
+    __lock: &'a StaticRwLock,
     __data: &'a UnsafeCell<T>,
     __marker: marker::NoSend,
 }
@@ -120,18 +120,18 @@ pub struct RWLockReadGuard<'a, T: 'a> {
 /// dropped.
 #[must_use]
 #[stable]
-pub struct RWLockWriteGuard<'a, T: 'a> {
-    __lock: &'a StaticRWLock,
+pub struct RwLockWriteGuard<'a, T: 'a> {
+    __lock: &'a StaticRwLock,
     __data: &'a UnsafeCell<T>,
     __poison: poison::Guard,
     __marker: marker::NoSend,
 }
 
-impl<T: Send + Sync> RWLock<T> {
-    /// Creates a new instance of an RWLock which is unlocked and read to go.
+impl<T: Send + Sync> RwLock<T> {
+    /// Creates a new instance of an RwLock which is unlocked and read to go.
     #[stable]
-    pub fn new(t: T) -> RWLock<T> {
-        RWLock { inner: box RWLOCK_INIT, data: UnsafeCell::new(t) }
+    pub fn new(t: T) -> RwLock<T> {
+        RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) }
     }
 
     /// Locks this rwlock with shared read access, blocking the current thread
@@ -148,14 +148,14 @@ pub fn new(t: T) -> RWLock<T> {
     ///
     /// # Failure
     ///
-    /// This function will return an error if the RWLock is poisoned. An RWLock
+    /// This function will return an error if the RwLock is poisoned. An RwLock
     /// is poisoned whenever a writer panics while holding an exclusive lock.
     /// The failure will occur immediately after the lock has been acquired.
     #[inline]
     #[stable]
-    pub fn read(&self) -> LockResult<RWLockReadGuard<T>> {
+    pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
         unsafe { self.inner.lock.read() }
-        RWLockReadGuard::new(&*self.inner, &self.data)
+        RwLockReadGuard::new(&*self.inner, &self.data)
     }
 
     /// Attempt to acquire this lock with shared read access.
@@ -169,15 +169,15 @@ pub fn read(&self) -> LockResult<RWLockReadGuard<T>> {
     ///
     /// # Failure
     ///
-    /// This function will return an error if the RWLock is poisoned. An RWLock
+    /// This function will return an error if the RwLock is poisoned. An RwLock
     /// is poisoned whenever a writer panics while holding an exclusive lock. An
     /// error will only be returned if the lock would have otherwise been
     /// acquired.
     #[inline]
     #[stable]
-    pub fn try_read(&self) -> TryLockResult<RWLockReadGuard<T>> {
+    pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
         if unsafe { self.inner.lock.try_read() } {
-            Ok(try!(RWLockReadGuard::new(&*self.inner, &self.data)))
+            Ok(try!(RwLockReadGuard::new(&*self.inner, &self.data)))
         } else {
             Err(TryLockError::WouldBlock)
         }
@@ -194,14 +194,14 @@ pub fn try_read(&self) -> TryLockResult<RWLockReadGuard<T>> {
     ///
     /// # Failure
     ///
-    /// This function will return an error if the RWLock is poisoned. An RWLock
+    /// This function will return an error if the RwLock is poisoned. An RwLock
     /// is poisoned whenever a writer panics while holding an exclusive lock.
     /// An error will be returned when the lock is acquired.
     #[inline]
     #[stable]
-    pub fn write(&self) -> LockResult<RWLockWriteGuard<T>> {
+    pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
         unsafe { self.inner.lock.write() }
-        RWLockWriteGuard::new(&*self.inner, &self.data)
+        RwLockWriteGuard::new(&*self.inner, &self.data)
     }
 
     /// Attempt to lock this rwlock with exclusive write access.
@@ -212,15 +212,15 @@ pub fn write(&self) -> LockResult<RWLockWriteGuard<T>> {
     ///
     /// # Failure
     ///
-    /// This function will return an error if the RWLock is poisoned. An RWLock
+    /// This function will return an error if the RwLock is poisoned. An RwLock
     /// is poisoned whenever a writer panics while holding an exclusive lock. An
     /// error will only be returned if the lock would have otherwise been
     /// acquired.
     #[inline]
     #[stable]
-    pub fn try_write(&self) -> TryLockResult<RWLockWriteGuard<T>> {
+    pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
         if unsafe { self.inner.lock.try_read() } {
-            Ok(try!(RWLockWriteGuard::new(&*self.inner, &self.data)))
+            Ok(try!(RwLockWriteGuard::new(&*self.inner, &self.data)))
         } else {
             Err(TryLockError::WouldBlock)
         }
@@ -228,7 +228,8 @@ pub fn try_write(&self) -> TryLockResult<RWLockWriteGuard<T>> {
 }
 
 #[unsafe_destructor]
-impl<T> Drop for RWLock<T> {
+#[stable]
+impl<T> Drop for RwLock<T> {
     fn drop(&mut self) {
         unsafe { self.inner.lock.destroy() }
     }
@@ -238,27 +239,27 @@ fn drop(&mut self) {
 unsafe impl Sync for Dummy {}
 static DUMMY: Dummy = Dummy(UnsafeCell { value: () });
 
-impl StaticRWLock {
+impl StaticRwLock {
     /// Locks this rwlock with shared read access, blocking the current thread
     /// until it can be acquired.
     ///
-    /// See `RWLock::read`.
+    /// See `RwLock::read`.
     #[inline]
-    #[unstable = "may be merged with RWLock in the future"]
-    pub fn read(&'static self) -> LockResult<RWLockReadGuard<'static, ()>> {
+    #[unstable = "may be merged with RwLock in the future"]
+    pub fn read(&'static self) -> LockResult<RwLockReadGuard<'static, ()>> {
         unsafe { self.lock.read() }
-        RWLockReadGuard::new(self, &DUMMY.0)
+        RwLockReadGuard::new(self, &DUMMY.0)
     }
 
     /// Attempt to acquire this lock with shared read access.
     ///
-    /// See `RWLock::try_read`.
+    /// See `RwLock::try_read`.
     #[inline]
-    #[unstable = "may be merged with RWLock in the future"]
+    #[unstable = "may be merged with RwLock in the future"]
     pub fn try_read(&'static self)
-                    -> TryLockResult<RWLockReadGuard<'static, ()>> {
+                    -> TryLockResult<RwLockReadGuard<'static, ()>> {
         if unsafe { self.lock.try_read() } {
-            Ok(try!(RWLockReadGuard::new(self, &DUMMY.0)))
+            Ok(try!(RwLockReadGuard::new(self, &DUMMY.0)))
         } else {
             Err(TryLockError::WouldBlock)
         }
@@ -267,23 +268,23 @@ pub fn try_read(&'static self)
     /// Lock this rwlock with exclusive write access, blocking the current
     /// thread until it can be acquired.
     ///
-    /// See `RWLock::write`.
+    /// See `RwLock::write`.
     #[inline]
-    #[unstable = "may be merged with RWLock in the future"]
-    pub fn write(&'static self) -> LockResult<RWLockWriteGuard<'static, ()>> {
+    #[unstable = "may be merged with RwLock in the future"]
+    pub fn write(&'static self) -> LockResult<RwLockWriteGuard<'static, ()>> {
         unsafe { self.lock.write() }
-        RWLockWriteGuard::new(self, &DUMMY.0)
+        RwLockWriteGuard::new(self, &DUMMY.0)
     }
 
     /// Attempt to lock this rwlock with exclusive write access.
     ///
-    /// See `RWLock::try_write`.
+    /// See `RwLock::try_write`.
     #[inline]
-    #[unstable = "may be merged with RWLock in the future"]
+    #[unstable = "may be merged with RwLock in the future"]
     pub fn try_write(&'static self)
-                     -> TryLockResult<RWLockWriteGuard<'static, ()>> {
+                     -> TryLockResult<RwLockWriteGuard<'static, ()>> {
         if unsafe { self.lock.try_write() } {
-            Ok(try!(RWLockWriteGuard::new(self, &DUMMY.0)))
+            Ok(try!(RwLockWriteGuard::new(self, &DUMMY.0)))
         } else {
             Err(TryLockError::WouldBlock)
         }
@@ -295,17 +296,17 @@ pub fn try_write(&'static self)
     /// active users of the lock, and this also doesn't prevent any future users
     /// of this lock. This method is required to be called to not leak memory on
     /// all platforms.
-    #[unstable = "may be merged with RWLock in the future"]
+    #[unstable = "may be merged with RwLock in the future"]
     pub unsafe fn destroy(&'static self) {
         self.lock.destroy()
     }
 }
 
-impl<'rwlock, T> RWLockReadGuard<'rwlock, T> {
-    fn new(lock: &'rwlock StaticRWLock, data: &'rwlock UnsafeCell<T>)
-           -> LockResult<RWLockReadGuard<'rwlock, T>> {
+impl<'rwlock, T> RwLockReadGuard<'rwlock, T> {
+    fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
+           -> LockResult<RwLockReadGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |_| {
-            RWLockReadGuard {
+            RwLockReadGuard {
                 __lock: lock,
                 __data: data,
                 __marker: marker::NoSend,
@@ -313,11 +314,11 @@ fn new(lock: &'rwlock StaticRWLock, data: &'rwlock UnsafeCell<T>)
         })
     }
 }
-impl<'rwlock, T> RWLockWriteGuard<'rwlock, T> {
-    fn new(lock: &'rwlock StaticRWLock, data: &'rwlock UnsafeCell<T>)
-           -> LockResult<RWLockWriteGuard<'rwlock, T>> {
+impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> {
+    fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
+           -> LockResult<RwLockWriteGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |guard| {
-            RWLockWriteGuard {
+            RwLockWriteGuard {
                 __lock: lock,
                 __data: data,
                 __poison: guard,
@@ -327,31 +328,36 @@ fn new(lock: &'rwlock StaticRWLock, data: &'rwlock UnsafeCell<T>)
     }
 }
 
-impl<'rwlock, T> Deref for RWLockReadGuard<'rwlock, T> {
+#[stable]
+impl<'rwlock, T> Deref for RwLockReadGuard<'rwlock, T> {
     type Target = T;
 
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
-impl<'rwlock, T> Deref for RWLockWriteGuard<'rwlock, T> {
+#[stable]
+impl<'rwlock, T> Deref for RwLockWriteGuard<'rwlock, T> {
     type Target = T;
 
     fn deref(&self) -> &T { unsafe { &*self.__data.get() } }
 }
-impl<'rwlock, T> DerefMut for RWLockWriteGuard<'rwlock, T> {
+#[stable]
+impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> {
     fn deref_mut(&mut self) -> &mut T {
         unsafe { &mut *self.__data.get() }
     }
 }
 
 #[unsafe_destructor]
-impl<'a, T> Drop for RWLockReadGuard<'a, T> {
+#[stable]
+impl<'a, T> Drop for RwLockReadGuard<'a, T> {
     fn drop(&mut self) {
         unsafe { self.__lock.lock.read_unlock(); }
     }
 }
 
 #[unsafe_destructor]
-impl<'a, T> Drop for RWLockWriteGuard<'a, T> {
+#[stable]
+impl<'a, T> Drop for RwLockWriteGuard<'a, T> {
     fn drop(&mut self) {
         self.__lock.poison.done(&self.__poison);
         unsafe { self.__lock.lock.write_unlock(); }
@@ -365,11 +371,11 @@ mod tests {
     use rand::{self, Rng};
     use sync::mpsc::channel;
     use thread::Thread;
-    use sync::{Arc, RWLock, StaticRWLock, RWLOCK_INIT};
+    use sync::{Arc, RwLock, StaticRwLock, RW_LOCK_INIT};
 
     #[test]
     fn smoke() {
-        let l = RWLock::new(());
+        let l = RwLock::new(());
         drop(l.read().unwrap());
         drop(l.write().unwrap());
         drop((l.read().unwrap(), l.read().unwrap()));
@@ -378,7 +384,7 @@ fn smoke() {
 
     #[test]
     fn static_smoke() {
-        static R: StaticRWLock = RWLOCK_INIT;
+        static R: StaticRwLock = RW_LOCK_INIT;
         drop(R.read().unwrap());
         drop(R.write().unwrap());
         drop((R.read().unwrap(), R.read().unwrap()));
@@ -388,7 +394,7 @@ fn static_smoke() {
 
     #[test]
     fn frob() {
-        static R: StaticRWLock = RWLOCK_INIT;
+        static R: StaticRwLock = RW_LOCK_INIT;
         static N: uint = 10;
         static M: uint = 1000;
 
@@ -414,7 +420,7 @@ fn frob() {
 
     #[test]
     fn test_rw_arc_poison_wr() {
-        let arc = Arc::new(RWLock::new(1i));
+        let arc = Arc::new(RwLock::new(1i));
         let arc2 = arc.clone();
         let _: Result<uint, _> = Thread::spawn(move|| {
             let _lock = arc2.write().unwrap();
@@ -425,7 +431,7 @@ fn test_rw_arc_poison_wr() {
 
     #[test]
     fn test_rw_arc_poison_ww() {
-        let arc = Arc::new(RWLock::new(1i));
+        let arc = Arc::new(RwLock::new(1i));
         let arc2 = arc.clone();
         let _: Result<uint, _> = Thread::spawn(move|| {
             let _lock = arc2.write().unwrap();
@@ -436,7 +442,7 @@ fn test_rw_arc_poison_ww() {
 
     #[test]
     fn test_rw_arc_no_poison_rr() {
-        let arc = Arc::new(RWLock::new(1i));
+        let arc = Arc::new(RwLock::new(1i));
         let arc2 = arc.clone();
         let _: Result<uint, _> = Thread::spawn(move|| {
             let _lock = arc2.read().unwrap();
@@ -447,7 +453,7 @@ fn test_rw_arc_no_poison_rr() {
     }
     #[test]
     fn test_rw_arc_no_poison_rw() {
-        let arc = Arc::new(RWLock::new(1i));
+        let arc = Arc::new(RwLock::new(1i));
         let arc2 = arc.clone();
         let _: Result<uint, _> = Thread::spawn(move|| {
             let _lock = arc2.read().unwrap();
@@ -459,7 +465,7 @@ fn test_rw_arc_no_poison_rw() {
 
     #[test]
     fn test_rw_arc() {
-        let arc = Arc::new(RWLock::new(0i));
+        let arc = Arc::new(RwLock::new(0i));
         let arc2 = arc.clone();
         let (tx, rx) = channel();
 
@@ -497,11 +503,11 @@ fn test_rw_arc() {
 
     #[test]
     fn test_rw_arc_access_in_unwind() {
-        let arc = Arc::new(RWLock::new(1i));
+        let arc = Arc::new(RwLock::new(1i));
         let arc2 = arc.clone();
         let _ = Thread::spawn(move|| -> () {
             struct Unwinder {
-                i: Arc<RWLock<int>>,
+                i: Arc<RwLock<int>>,
             }
             impl Drop for Unwinder {
                 fn drop(&mut self) {
index c0ff674ba0f7dad5870d64df1f644bac1ceb3a53..505819fbf8a246cf4ee618b64e89cb921dd8d8a7 100644 (file)
@@ -99,6 +99,7 @@ pub fn access(&self) -> SemaphoreGuard {
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<'a> Drop for SemaphoreGuard<'a> {
     fn drop(&mut self) {
         self.sem.release();
index a441e55a732b01049a187df94b611ce36e8edafe..a31dcc9884f465fa74c4311f443ac670853c0dac 100644 (file)
@@ -14,7 +14,7 @@
 use io::{self, IoError, IoResult};
 use prelude::v1::*;
 use sys::{last_error, retry};
-use c_str::CString;
+use ffi::CString;
 use num::Int;
 use path::BytesContainer;
 use collections;
index 3f67b284f688794d2611944e327463d0fce373c3..4cf891ac4985eba360859a1cff038719ce3ca9a8 100644 (file)
 use self::SocketStatus::*;
 use self::InAddr::*;
 
-use c_str::ToCStr;
+use ffi::CString;
+use ffi;
 use io::net::addrinfo;
 use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
 use io::{IoResult, IoError};
 use libc::{self, c_char, c_int};
-use c_str::CString;
 use mem;
 use num::Int;
 use ptr::{self, null, null_mut};
+use str;
 use sys::{self, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
           wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
           decode_error_detailed};
@@ -234,9 +235,9 @@ pub fn get_host_addresses(host: Option<&str>, servname: Option<&str>,
 
     assert!(host.is_some() || servname.is_some());
 
-    let c_host = host.map(|x| x.to_c_str());
+    let c_host = host.map(|x| CString::from_slice(x.as_bytes()));
     let c_host = c_host.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
-    let c_serv = servname.map(|x| x.to_c_str());
+    let c_serv = servname.map(|x| CString::from_slice(x.as_bytes()));
     let c_serv = c_serv.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
 
     let hint = hint.map(|hint| {
@@ -324,7 +325,8 @@ pub fn get_address_name(addr: IpAddr) -> Result<String, IoError> {
     }
 
     unsafe {
-        Ok(CString::new(hostbuf.as_ptr(), false).as_str().unwrap().to_string())
+        Ok(str::from_utf8(ffi::c_str_to_bytes(&hostbuf.as_ptr()))
+               .unwrap().to_string())
     }
 }
 
index 5b261ea6b9e58a85e9c5a94bc6da6ae4304ff890..ca268a8f27ff34680a915eff95255b7f4acd2093 100644 (file)
 /// to symbols. This is a bit of a hokey implementation as-is, but it works for
 /// all unix platforms we support right now, so it at least gets the job done.
 
-use c_str::CString;
-use io::{IoResult, Writer};
+use prelude::v1::*;
+
+use ffi;
+use io::IoResult;
 use libc;
 use mem;
-use option::Option::{self, Some, None};
-use result::Result::{Ok, Err};
+use str;
 use sync::{StaticMutex, MUTEX_INIT};
 
 use sys_common::backtrace::*;
 #[cfg(all(target_os = "ios", target_arch = "arm"))]
 #[inline(never)]
 pub fn write(w: &mut Writer) -> IoResult<()> {
-    use iter::{IteratorExt, range};
     use result;
-    use slice::SliceExt;
 
     extern {
         fn backtrace(buf: *mut *mut libc::c_void,
@@ -234,19 +233,15 @@ fn dladdr(addr: *const libc::c_void,
         output(w, idx,addr, None)
     } else {
         output(w, idx, addr, Some(unsafe {
-            CString::new(info.dli_sname, false)
+            ffi::c_str_to_bytes(&info.dli_sname)
         }))
     }
 }
 
 #[cfg(not(any(target_os = "macos", target_os = "ios")))]
 fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
-    use iter::{Iterator, IteratorExt};
     use os;
-    use path::GenericPath;
-    use ptr::PtrExt;
     use ptr;
-    use slice::SliceExt;
 
     ////////////////////////////////////////////////////////////////////////
     // libbacktrace.h API
@@ -368,15 +363,15 @@ unsafe fn init_state() -> *mut backtrace_state {
     if ret == 0 || data.is_null() {
         output(w, idx, addr, None)
     } else {
-        output(w, idx, addr, Some(unsafe { CString::new(data, false) }))
+        output(w, idx, addr, Some(unsafe { ffi::c_str_to_bytes(&data) }))
     }
 }
 
 // Finally, after all that work above, we can emit a symbol.
 fn output(w: &mut Writer, idx: int, addr: *mut libc::c_void,
-          s: Option<CString>) -> IoResult<()> {
+          s: Option<&[u8]>) -> IoResult<()> {
     try!(write!(w, "  {:2}: {:2$} - ", idx, addr, HEX_WIDTH));
-    match s.as_ref().and_then(|c| c.as_str()) {
+    match s.and_then(|s| str::from_utf8(s).ok()) {
         Some(string) => try!(demangle(w, string)),
         None => try!(write!(w, "<unknown>")),
     }
index b49ace8e2f8d83509a13525f0744f7d206d1d28d..1ad775517bba714aac62f8ea639ed31660d1d935 100644 (file)
@@ -12,7 +12,7 @@
 
 use prelude::v1::*;
 
-use c_str::{CString, ToCStr};
+use ffi::{self, CString};
 use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
 use io::{IoResult, FileStat, SeekStyle};
 use io::{Read, Truncate, SeekCur, SeekSet, ReadWrite, SeekEnd, Append};
@@ -150,6 +150,10 @@ fn drop(&mut self) {
     }
 }
 
+fn cstr(path: &Path) -> CString {
+    CString::from_slice(path.as_vec())
+}
+
 pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
     let flags = match fm {
         Open => 0,
@@ -165,7 +169,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
                             libc::S_IRUSR | libc::S_IWUSR),
     };
 
-    let path = path.to_c_str();
+    let path = cstr(path);
     match retry(|| unsafe { libc::open(path.as_ptr(), flags, mode) }) {
         -1 => Err(super::last_error()),
         fd => Ok(FileDesc::new(fd, true)),
@@ -173,7 +177,7 @@ pub fn open(path: &Path, fm: FileMode, fa: FileAccess) -> IoResult<FileDesc> {
 }
 
 pub fn mkdir(p: &Path, mode: uint) -> IoResult<()> {
-    let p = p.to_c_str();
+    let p = cstr(p);
     mkerr_libc(unsafe { libc::mkdir(p.as_ptr(), mode as libc::mode_t) })
 }
 
@@ -182,7 +186,6 @@ pub fn readdir(p: &Path) -> IoResult<Vec<Path>> {
     use libc::{opendir, readdir_r, closedir};
 
     fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
-        let root = unsafe { CString::new(root.as_ptr(), false) };
         let root = Path::new(root);
 
         dirs.into_iter().filter(|path| {
@@ -199,7 +202,7 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
     let mut buf = Vec::<u8>::with_capacity(size as uint);
     let ptr = buf.as_mut_ptr() as *mut dirent_t;
 
-    let p = p.to_c_str();
+    let p = CString::from_slice(p.as_vec());
     let dir_ptr = unsafe {opendir(p.as_ptr())};
 
     if dir_ptr as uint != 0 {
@@ -207,10 +210,9 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
         let mut entry_ptr = 0 as *mut dirent_t;
         while unsafe { readdir_r(dir_ptr, ptr, &mut entry_ptr) == 0 } {
             if entry_ptr.is_null() { break }
-            let cstr = unsafe {
-                CString::new(rust_list_dir_val(entry_ptr), false)
-            };
-            paths.push(Path::new(cstr));
+            paths.push(unsafe {
+                Path::new(ffi::c_str_to_bytes(&rust_list_dir_val(entry_ptr)))
+            });
         }
         assert_eq!(unsafe { closedir(dir_ptr) }, 0);
         Ok(prune(&p, paths))
@@ -220,39 +222,39 @@ fn prune(root: &CString, dirs: Vec<Path>) -> Vec<Path> {
 }
 
 pub fn unlink(p: &Path) -> IoResult<()> {
-    let p = p.to_c_str();
+    let p = cstr(p);
     mkerr_libc(unsafe { libc::unlink(p.as_ptr()) })
 }
 
 pub fn rename(old: &Path, new: &Path) -> IoResult<()> {
-    let old = old.to_c_str();
-    let new = new.to_c_str();
+    let old = cstr(old);
+    let new = cstr(new);
     mkerr_libc(unsafe {
         libc::rename(old.as_ptr(), new.as_ptr())
     })
 }
 
 pub fn chmod(p: &Path, mode: uint) -> IoResult<()> {
-    let p = p.to_c_str();
+    let p = cstr(p);
     mkerr_libc(retry(|| unsafe {
         libc::chmod(p.as_ptr(), mode as libc::mode_t)
     }))
 }
 
 pub fn rmdir(p: &Path) -> IoResult<()> {
-    let p = p.to_c_str();
+    let p = cstr(p);
     mkerr_libc(unsafe { libc::rmdir(p.as_ptr()) })
 }
 
 pub fn chown(p: &Path, uid: int, gid: int) -> IoResult<()> {
-    let p = p.to_c_str();
+    let p = cstr(p);
     mkerr_libc(retry(|| unsafe {
         libc::chown(p.as_ptr(), uid as libc::uid_t, gid as libc::gid_t)
     }))
 }
 
 pub fn readlink(p: &Path) -> IoResult<Path> {
-    let c_path = p.to_c_str();
+    let c_path = cstr(p);
     let p = c_path.as_ptr();
     let mut len = unsafe { libc::pathconf(p as *mut _, libc::_PC_NAME_MAX) };
     if len == -1 {
@@ -273,14 +275,14 @@ pub fn readlink(p: &Path) -> IoResult<Path> {
 }
 
 pub fn symlink(src: &Path, dst: &Path) -> IoResult<()> {
-    let src = src.to_c_str();
-    let dst = dst.to_c_str();
+    let src = cstr(src);
+    let dst = cstr(dst);
     mkerr_libc(unsafe { libc::symlink(src.as_ptr(), dst.as_ptr()) })
 }
 
 pub fn link(src: &Path, dst: &Path) -> IoResult<()> {
-    let src = src.to_c_str();
-    let dst = dst.to_c_str();
+    let src = cstr(src);
+    let dst = cstr(dst);
     mkerr_libc(unsafe { libc::link(src.as_ptr(), dst.as_ptr()) })
 }
 
@@ -328,7 +330,7 @@ fn gen(_stat: &libc::stat) -> u64 { 0 }
 }
 
 pub fn stat(p: &Path) -> IoResult<FileStat> {
-    let p = p.to_c_str();
+    let p = cstr(p);
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     match unsafe { libc::stat(p.as_ptr(), &mut stat) } {
         0 => Ok(mkstat(&stat)),
@@ -337,7 +339,7 @@ pub fn stat(p: &Path) -> IoResult<FileStat> {
 }
 
 pub fn lstat(p: &Path) -> IoResult<FileStat> {
-    let p = p.to_c_str();
+    let p = cstr(p);
     let mut stat: libc::stat = unsafe { mem::zeroed() };
     match unsafe { libc::lstat(p.as_ptr(), &mut stat) } {
         0 => Ok(mkstat(&stat)),
@@ -346,7 +348,7 @@ pub fn lstat(p: &Path) -> IoResult<FileStat> {
 }
 
 pub fn utime(p: &Path, atime: u64, mtime: u64) -> IoResult<()> {
-    let p = p.to_c_str();
+    let p = cstr(p);
     let buf = libc::utimbuf {
         actime: (atime / 1000) as libc::time_t,
         modtime: (mtime / 1000) as libc::time_t,
index ea0d230e8b210c751d80df67a093e7f25f146dd5..6a408aa60f0bfb2aa8bbcbbf8fe3a691fb681e0e 100644 (file)
 #![allow(unused_unsafe)]
 #![allow(unused_mut)]
 
-extern crate libc;
-
-use num;
-use num::{Int, SignedInt};
 use prelude::v1::*;
+
+use ffi;
 use io::{self, IoResult, IoError};
+use libc;
+use num::{Int, SignedInt};
+use num;
+use str;
 use sys_common::mkerr_libc;
 
 macro_rules! helper_init { (static $name:ident: Helper<$m:ty>) => (
@@ -78,11 +80,10 @@ pub fn last_net_error() -> IoError {
 }
 
 pub fn last_gai_error(s: libc::c_int) -> IoError {
-    use c_str::CString;
 
     let mut err = decode_error(s);
     err.detail = Some(unsafe {
-        CString::new(gai_strerror(s), false).as_str().unwrap().to_string()
+        str::from_utf8(ffi::c_str_to_bytes(&gai_strerror(s))).unwrap().to_string()
     });
     err
 }
index 181b8fdd0f8a11af8e610cd751b1aebc6d72da48..175c4e2e353f91044fa0453395c27f173671a870 100644 (file)
 
 use prelude::v1::*;
 
-use c_str::ToCStr;
 use error::{FromError, Error};
+use ffi::{self, CString};
 use fmt;
 use io::{IoError, IoResult};
 use libc::{self, c_int, c_char, c_void};
+use os::TMPBUF_SZ;
 use os;
 use path::{BytesContainer};
 use ptr;
+use str;
 use sys::fs::FileDesc;
 
-use os::TMPBUF_SZ;
-
 const BUF_BYTES : uint = 2048u;
 
 /// Returns the platform-specific value of errno
@@ -108,7 +108,8 @@ fn __xpg_strerror_r(errnum: c_int,
             panic!("strerror_r failure");
         }
 
-        String::from_raw_buf(p as *const u8)
+        let p = p as *const _;
+        str::from_utf8(ffi::c_str_to_bytes(&p)).unwrap().to_string()
     }
 }
 
@@ -122,21 +123,17 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
 }
 
 pub fn getcwd() -> IoResult<Path> {
-    use c_str::CString;
-
     let mut buf = [0 as c_char; BUF_BYTES];
     unsafe {
         if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
             Err(IoError::last_error())
         } else {
-            Ok(Path::new(CString::new(buf.as_ptr(), false)))
+            Ok(Path::new(ffi::c_str_to_bytes(&buf.as_ptr())))
         }
     }
 }
 
 pub unsafe fn get_env_pairs() -> Vec<Vec<u8>> {
-    use c_str::CString;
-
     extern {
         fn rust_env_pairs() -> *const *const c_char;
     }
@@ -147,8 +144,7 @@ pub unsafe fn get_env_pairs() -> Vec<Vec<u8>> {
     }
     let mut result = Vec::new();
     while *environ != 0 as *const _ {
-        let env_pair =
-            CString::new(*environ, false).as_bytes_no_nul().to_vec();
+        let env_pair = ffi::c_str_to_bytes(&*environ).to_vec();
         result.push(env_pair);
         environ = environ.offset(1);
     }
@@ -234,14 +230,13 @@ pub fn load_self() -> Option<Vec<u8>> {
 }
 
 pub fn chdir(p: &Path) -> IoResult<()> {
-    p.with_c_str(|buf| {
-        unsafe {
-            match libc::chdir(buf) == (0 as c_int) {
-                true => Ok(()),
-                false => Err(IoError::last_error()),
-            }
+    let p = CString::from_slice(p.as_vec());
+    unsafe {
+        match libc::chdir(p.as_ptr()) == (0 as c_int) {
+            true => Ok(()),
+            false => Err(IoError::last_error()),
         }
-    })
+    }
 }
 
 pub fn page_size() -> uint {
index 9063fbc2ba955b9466f3b12b9b9164f8a9397b36..158a1ce220411439bfeb2f188fdb002bf12ed14d 100644 (file)
@@ -10,8 +10,8 @@
 
 use prelude::v1::*;
 
+use ffi::CString;
 use libc;
-use c_str::CString;
 use mem;
 use sync::{Arc, Mutex};
 use sync::atomic::{AtomicBool, Ordering};
@@ -48,7 +48,7 @@ fn addr_to_sockaddr_un(addr: &CString,
     }
     s.sun_family = libc::AF_UNIX as libc::sa_family_t;
     for (slot, value) in s.sun_path.iter_mut().zip(addr.iter()) {
-        *slot = value;
+        *slot = *value;
     }
 
     // count the null terminator
index b73919fe2a2cc5b063b65624bea6c1a467b734dd..5bc6b0c703b1c9c90057820cb37f2880bec164aa 100644 (file)
@@ -11,8 +11,8 @@
 use prelude::v1::*;
 use self::Req::*;
 
-use c_str::{CString, ToCStr};
 use collections;
+use ffi::CString;
 use hash::Hash;
 use io::process::{ProcessExit, ExitStatus, ExitSignal};
 use io::{self, IoResult, IoError, EndOfFile};
@@ -101,7 +101,7 @@ unsafe fn set_cloexec(fd: c_int) {
 
                 // We may use this in the child, so perform allocations before the
                 // fork
-                let devnull = "/dev/null".to_c_str();
+                let devnull = b"/dev/null\0";
 
                 set_cloexec(output.fd());
 
@@ -204,7 +204,7 @@ fn fail(output: &mut FileDesc) -> ! {
                             } else {
                                 libc::O_RDWR
                             };
-                            libc::open(devnull.as_ptr(), flags, 0)
+                            libc::open(devnull.as_ptr() as *const _, flags, 0)
                         }
                         Some(obj) => {
                             let fd = obj.as_inner().fd();
index 11f29232a925d0e3625a607a9ee1d7c978e5f5db..62f3242a2062580360ee277bc83ce9be8cf97767 100644 (file)
@@ -54,7 +54,7 @@
 use mem;
 use os;
 use ptr;
-use sync::atomic::{mod, Ordering};
+use sync::atomic::{self, Ordering};
 use sync::mpsc::{channel, Sender, Receiver, TryRecvError};
 use sys::c;
 use sys::fs::FileDesc;
index 319a458087b9b51f949c997cf08c101ca55b662f..4ccecfd1f5f2e6cc35f754cbe7049dcd23181388 100644 (file)
@@ -21,7 +21,8 @@
 /// copy of that function in my mingw install (maybe it was broken?). Instead,
 /// this takes the route of using StackWalk64 in order to walk the stack.
 
-use c_str::CString;
+use dynamic_lib::DynamicLibrary;
+use ffi;
 use intrinsics;
 use io::{IoResult, Writer};
 use libc;
 use option::Option::{Some, None};
 use path::Path;
 use result::Result::{Ok, Err};
-use sync::{StaticMutex, MUTEX_INIT};
 use slice::SliceExt;
-use str::StrExt;
-use dynamic_lib::DynamicLibrary;
+use str::{self, StrExt};
+use sync::{StaticMutex, MUTEX_INIT};
 
 use sys_common::backtrace::*;
 
@@ -357,11 +357,11 @@ macro_rules! sym{ ($e:expr, $t:ident) => (unsafe {
 
         if ret == libc::TRUE {
             try!(write!(w, " - "));
-            let cstr = unsafe { CString::new(info.Name.as_ptr(), false) };
-            let bytes = cstr.as_bytes();
-            match cstr.as_str() {
-                Some(s) => try!(demangle(w, s)),
-                None => try!(w.write(bytes[..bytes.len()-1])),
+            let ptr = info.Name.as_ptr() as *const libc::c_char;
+            let bytes = unsafe { ffi::c_str_to_bytes(&ptr) };
+            match str::from_utf8(bytes) {
+                Ok(s) => try!(demangle(w, s)),
+                Err(..) => try!(w.write(bytes[..bytes.len()-1])),
             }
         }
         try!(w.write(&['\n' as u8]));
index 1ee57434fb91ada83e4cad503654a6d7b9332afd..945c2e8e7d156ce501ca029f5b54483123a3acd5 100644 (file)
@@ -133,7 +133,7 @@ pub mod compat {
     use intrinsics::{atomic_store_relaxed, transmute};
     use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
     use prelude::v1::*;
-    use c_str::ToCStr;
+    use ffi::CString;
 
     extern "system" {
         fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
@@ -147,14 +147,13 @@ pub mod compat {
     unsafe fn store_func(ptr: *mut uint, module: &str, symbol: &str, fallback: uint) {
         let mut module: Vec<u16> = module.utf16_units().collect();
         module.push(0);
-        symbol.with_c_str(|symbol| {
-            let handle = GetModuleHandleW(module.as_ptr());
-            let func: uint = transmute(GetProcAddress(handle, symbol));
-            atomic_store_relaxed(ptr, if func == 0 {
-                fallback
-            } else {
-                func
-            })
+        let symbol = CString::from_slice(symbol.as_bytes());
+        let handle = GetModuleHandleW(module.as_ptr());
+        let func: uint = transmute(GetProcAddress(handle, symbol.as_ptr()));
+        atomic_store_relaxed(ptr, if func == 0 {
+            fallback
+        } else {
+            func
         })
     }
 
index 9a9423006568020e2d83e73fae538d8fd4c944b7..f8c75335b35dc31059790965e7c89e54f52322ec 100644 (file)
@@ -13,7 +13,6 @@
 use alloc::arc::Arc;
 use libc::{self, c_int};
 
-use c_str::CString;
 use mem;
 use sys::os::fill_utf16_buf_and_decode;
 use path;
index 9057515cad294c51f849a0fff470004e77745c97..9996909f2f5bbc18a9781018bd4dd4aaaf952fd1 100644 (file)
 use prelude::v1::*;
 
 use libc;
-use c_str::CString;
+use ffi::CString;
+use io::{self, IoError, IoResult};
 use mem;
 use ptr;
-use sync::{Arc, Mutex};
+use str;
 use sync::atomic::{AtomicBool, Ordering};
-use io::{self, IoError, IoResult};
+use sync::{Arc, Mutex};
 
 use sys_common::{self, eof};
 
-use super::{c, os, timer, to_utf16, decode_error_detailed};
+use super::{c, os, timer, decode_error_detailed};
+
+fn to_utf16(c: &CString) -> IoResult<Vec<u16>> {
+    super::to_utf16(str::from_utf8(c.as_bytes()).ok())
+}
 
 struct Event(libc::HANDLE);
 
@@ -270,7 +275,7 @@ fn try_connect(p: *const u16) -> Option<libc::HANDLE> {
     }
 
     pub fn connect(addr: &CString, timeout: Option<u64>) -> IoResult<UnixStream> {
-        let addr = try!(to_utf16(addr.as_str()));
+        let addr = try!(to_utf16(addr));
         let start = timer::now();
         loop {
             match UnixStream::try_connect(addr.as_ptr()) {
@@ -571,7 +576,7 @@ pub fn bind(addr: &CString) -> IoResult<UnixListener> {
         // Although we technically don't need the pipe until much later, we
         // create the initial handle up front to test the validity of the name
         // and such.
-        let addr_v = try!(to_utf16(addr.as_str()));
+        let addr_v = try!(to_utf16(addr));
         let ret = unsafe { pipe(addr_v.as_ptr(), true) };
         if ret == libc::INVALID_HANDLE_VALUE {
             Err(super::last_error())
@@ -661,7 +666,7 @@ pub fn accept(&mut self) -> IoResult<UnixStream> {
         // proceed in accepting new clients in the future
         if self.inner.closed.load(Ordering::SeqCst) { return Err(eof()) }
 
-        let name = try!(to_utf16(self.listener.name.as_str()));
+        let name = try!(to_utf16(&self.listener.name));
 
         // Once we've got a "server handle", we need to wait for a client to
         // connect. The ConnectNamedPipe function will block this thread until
@@ -753,7 +758,7 @@ pub fn handle(&self) -> libc::HANDLE {
 
 impl Clone for UnixAcceptor {
     fn clone(&self) -> UnixAcceptor {
-        let name = to_utf16(self.listener.name.as_str()).ok().unwrap();
+        let name = to_utf16(&self.listener.name).ok().unwrap();
         UnixAcceptor {
             inner: self.inner.clone(),
             event: Event::new(true, false).ok().unwrap(),
index 81e8f974a12238abf9fad4e13d79571078cc050f..7b667416b171418f0dedaaedaf6694a8de70da59 100644 (file)
 
 use prelude::v1::*;
 
+use collections;
+use ffi::CString;
+use hash::Hash;
+use io::fs::PathExtensions;
+use io::process::{ProcessExit, ExitStatus, ExitSignal};
+use io::{IoResult, IoError};
+use io;
 use libc::{pid_t, c_void, c_int};
 use libc;
-use c_str::{CString, ToCStr};
-use io;
 use mem;
 use os;
-use ptr;
-use io::process::{ProcessExit, ExitStatus, ExitSignal};
-use collections;
 use path::BytesContainer;
-use hash::Hash;
-use io::{IoResult, IoError};
-
+use ptr;
+use str;
+use sys::fs::FileDesc;
 use sys::fs;
 use sys::{self, retry, c, wouldblock, set_nonblocking, ms_to_timeval, timer};
-use sys::fs::FileDesc;
 use sys_common::helper_thread::Helper;
 use sys_common::{AsInner, mkerr_libc, timeout};
 
-use io::fs::PathExtensions;
-
 pub use sys_common::ProcessConfig;
 
 /// A value representing a child process.
@@ -142,10 +141,10 @@ pub fn spawn<K, V, C, P>(cfg: &C, in_fd: Option<P>,
                 // Split the value and test each path to see if the
                 // program exists.
                 for path in os::split_paths(v.container_as_bytes()).into_iter() {
-                    let path = path.join(cfg.program().as_bytes_no_nul())
+                    let path = path.join(cfg.program().as_bytes())
                                    .with_extension(os::consts::EXE_EXTENSION);
                     if path.exists() {
-                        return Some(path.to_c_str())
+                        return Some(CString::from_slice(path.as_vec()))
                     }
                 }
                 break
@@ -363,11 +362,11 @@ fn zeroed_process_information() -> libc::types::os::arch::extra::PROCESS_INFORMA
 
 fn make_command_line(prog: &CString, args: &[CString]) -> String {
     let mut cmd = String::new();
-    append_arg(&mut cmd, prog.as_str()
+    append_arg(&mut cmd, str::from_utf8(prog.as_bytes()).ok()
                              .expect("expected program name to be utf-8 encoded"));
     for arg in args.iter() {
         cmd.push(' ');
-        append_arg(&mut cmd, arg.as_str()
+        append_arg(&mut cmd, str::from_utf8(arg.as_bytes()).ok()
                                 .expect("expected argument to be utf-8 encoded"));
     }
     return cmd;
@@ -449,7 +448,7 @@ fn with_dirp<T, F>(d: Option<&CString>, cb: F) -> T where
 {
     match d {
       Some(dir) => {
-          let dir_str = dir.as_str()
+          let dir_str = str::from_utf8(dir.as_bytes()).ok()
                            .expect("expected workingdirectory to be utf-8 encoded");
           let mut dir_str: Vec<u16> = dir_str.utf16_units().collect();
           dir_str.push(0);
@@ -467,19 +466,17 @@ fn free_handle(handle: *mut ()) {
 
 #[cfg(test)]
 mod tests {
-    use c_str::ToCStr;
+    use prelude::v1::*;
+    use str;
+    use ffi::CString;
+    use super::make_command_line;
 
     #[test]
     fn test_make_command_line() {
-        use prelude::v1::*;
-        use str;
-        use c_str::CString;
-        use super::make_command_line;
-
         fn test_wrapper(prog: &str, args: &[&str]) -> String {
-            make_command_line(&prog.to_c_str(),
+            make_command_line(&CString::from_slice(prog.as_bytes()),
                               args.iter()
-                                  .map(|a| a.to_c_str())
+                                  .map(|a| CString::from_slice(a.as_bytes()))
                                   .collect::<Vec<CString>>()
                                   .as_slice())
         }
index 63112327415d238e50f0e95c46f28ed73666b4b2..cc82d38ae2af1f01140701dd4e6894296fc594d6 100644 (file)
@@ -423,6 +423,7 @@ pub fn detach(mut self) {
 }
 
 #[unsafe_destructor]
+#[stable]
 impl<T: Send> Drop for JoinGuard<T> {
     fn drop(&mut self) {
         if !self.joined {
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 f40b62182d42c73bbb1fbcbd11c215a51501711f..e76dcef226ddc3e79eec371d7c8451fb1db9a4e3 100644 (file)
 
 //! Operations on tuples
 //!
-//! To access a single element of a tuple one can use the following
-//! methods:
+//! To access the _N_-th element of a tuple one can use `N` itself
+//! as a field of the tuple.
 //!
-//! * `valN` - returns a value of _N_-th element
-//! * `refN` - returns a reference to _N_-th element
-//! * `mutN` - returns a mutable reference to _N_-th element
-//!
-//! Indexing starts from zero, so `val0` returns first value, `val1`
+//! Indexing starts from zero, so `0` returns first value, `1`
 //! returns second value, and so on. In general, a tuple with _S_
-//! elements provides aforementioned methods suffixed with numbers
-//! from `0` to `S-1`. Traits which contain these methods are
-//! implemented for tuples with up to 12 elements.
+//! elements provides aforementioned fields from `0` to `S-1`.
 //!
 //! If every type inside a tuple implements one of the following
 //! traits, then a tuple itself also implements it.
 //!
 //! # Examples
 //!
+//! Accessing elements of a tuple at specified indices:
+//!
+//! ```
+//! let x = ("colorless",  "green", "ideas", "sleep", "furiously");
+//! assert_eq!(x.3, "sleep");
+//!
+//! let v = (3i, 3i);
+//! let u = (1i, -5i);
+//! assert_eq!(v.0 * u.0 + v.1 * u.1, -12i);
+//! ```
+//!
 //! Using traits implemented for tuples:
 //!
 //! ```
index e779821342a17dc76650d62d1794ba0da6762a82..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_>;
@@ -572,7 +572,7 @@ pub enum Pat_ {
     PatStruct(Path, Vec<Spanned<FieldPat>>, bool),
     PatTup(Vec<P<Pat>>),
     PatBox(P<Pat>),
-    PatRegion(P<Pat>), // reference pattern
+    PatRegion(P<Pat>, Mutability), // reference pattern
     PatLit(P<Expr>),
     PatRange(P<Expr>, P<Expr>),
     /// [a, b, ..i, y, z] is represented as:
@@ -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 4026da6cf8e478ed48e90eeb026f1b2ca3111133..5e03afec16cf8709e1e5a92a047e87d39ef9a6b5 100644 (file)
@@ -633,7 +633,7 @@ fn walk_pat_<G>(pat: &Pat, it: &mut G) -> bool where G: FnMut(&Pat) -> bool {
             PatEnum(_, Some(ref s)) | PatTup(ref s) => {
                 s.iter().all(|p| walk_pat_(&**p, it))
             }
-            PatBox(ref s) | PatRegion(ref s) => {
+            PatBox(ref s) | PatRegion(ref s, _) => {
                 walk_pat_(&**s, it)
             }
             PatVec(ref before, ref slice, ref after) => {
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 1fb8189c63c818769a7a0b9c2df02e264f10b86d..1aa430c4a08299b325ec73fd42dbb8934ffa4443 100644 (file)
@@ -937,7 +937,7 @@ fn build_enum_match_tuple(
                                                                          &**variant,
                                                                          self_arg_name,
                                                                          ast::MutImmutable);
-                    (cx.pat(sp, ast::PatRegion(p)), idents)
+                    (cx.pat(sp, ast::PatRegion(p, ast::MutImmutable)), idents)
                 };
 
                 // A single arm has form (&VariantK, &VariantK, ...) => BodyK
index b9acde4bf6be9ac21195a30d6b3ce454fe9fdc7f..844bd80d1610a4674e91f01293ab5881dd5dade1 100644 (file)
@@ -25,20 +25,14 @@ pub fn expand_deriving_hash<F>(cx: &mut ExtCtxt,
     F: FnOnce(P<Item>),
 {
 
-    let (path, generics, args) = if cx.ecfg.deriving_hash_type_parameter {
-        (Path::new_(vec!("std", "hash", "Hash"), None,
-                    vec!(box Literal(Path::new_local("__S"))), true),
-         LifetimeBounds {
-             lifetimes: Vec::new(),
-             bounds: vec!(("__S",
-                           vec!(Path::new(vec!("std", "hash", "Writer"))))),
-         },
-         Path::new_local("__S"))
-    } else {
-        (Path::new(vec!("std", "hash", "Hash")),
-         LifetimeBounds::empty(),
-         Path::new(vec!("std", "hash", "sip", "SipState")))
+    let path = Path::new_(vec!("std", "hash", "Hash"), None,
+                          vec!(box Literal(Path::new_local("__S"))), true);
+    let generics = LifetimeBounds {
+        lifetimes: Vec::new(),
+        bounds: vec!(("__S",
+                      vec!(Path::new(vec!("std", "hash", "Writer"))))),
     };
+    let args = Path::new_local("__S");
     let inline = cx.meta_word(span, InternedString::new("inline"));
     let attrs = vec!(cx.attribute(span, inline));
     let hash_trait_def = TraitDef {
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 b3f30dd4581c9ed6edd5453a7621df805fc61cc7..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)
     }
 }
 
@@ -1161,7 +1171,6 @@ fn new_span(cx: &ExtCtxt, sp: Span) -> Span {
 
 pub struct ExpansionConfig {
     pub crate_name: String,
-    pub deriving_hash_type_parameter: bool,
     pub enable_quotes: bool,
     pub recursion_limit: uint,
 }
@@ -1170,38 +1179,23 @@ impl ExpansionConfig {
     pub fn default(crate_name: String) -> ExpansionConfig {
         ExpansionConfig {
             crate_name: crate_name,
-            deriving_hash_type_parameter: false,
             enable_quotes: false,
             recursion_limit: 64,
         }
     }
 }
 
-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() {
@@ -1290,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");
     }
@@ -1300,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};
@@ -1397,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(
@@ -1409,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 e46bd7ac4bc73c07ab63472edc0a2dcd3a6a3988..f1b52fa33c386a3bd439ad9b9c2e9e4f0ed308c4 100644 (file)
@@ -85,14 +85,14 @@ pub fn to_tokens(cx: &ExtCtxt) -> ~[TokenTree] {
     */
 
     // FIXME: Move this trait to pprust and get rid of *_to_str?
-    pub trait ToSource for Sized? {
+    pub trait ToSource {
         // Takes a thing and generates a string containing rust code for it.
         fn to_source(&self) -> String;
     }
 
     // FIXME (Issue #16472): This should go away after ToToken impls
     // are revised to go directly to token-trees.
-    trait ToSourceWithHygiene for Sized? : ToSource {
+    trait ToSourceWithHygiene : ToSource {
         // Takes a thing and generates a string containing rust code
         // for it, encoding Idents as special byte sequences to
         // maintain hygiene across serialization and deserialization.
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 cb6277069e1a2b4ccbf3078c7ee23c04eed185df..0810d4ee93ac700cf5c650d7cc6fa983524b5935 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", Active),
-    ("macro_rules", Active),
+    ("globs", Accepted),
+    ("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),
@@ -54,7 +54,7 @@
     ("lang_items", Active),
 
     ("simd", Active),
-    ("default_type_params", Active),
+    ("default_type_params", Accepted),
     ("quote", Active),
     ("link_llvm_intrinsics", Active),
     ("linkage", Active),
     ("import_shadowing", Active),
     ("advanced_slice_patterns", Active),
     ("tuple_indexing", Accepted),
-    ("associated_types", Active),
+    ("associated_types", Accepted),
     ("visible_private_types", Active),
     ("slicing_syntax", Active),
 
     ("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),
@@ -112,7 +114,6 @@ enum Status {
 /// A set of features to be used by later passes.
 #[derive(Copy)]
 pub struct Features {
-    pub default_type_params: bool,
     pub unboxed_closures: bool,
     pub rustc_diagnostic_macros: bool,
     pub import_shadowing: bool,
@@ -125,7 +126,6 @@ pub struct Features {
 impl Features {
     pub fn new() -> Features {
         Features {
-            default_type_params: false,
             unboxed_closures: false,
             rustc_diagnostic_macros: false,
             import_shadowing: false,
@@ -163,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");
         }
@@ -232,19 +211,13 @@ fn visit_name(&mut self, sp: Span, name: ast::Name) {
 
     fn visit_view_item(&mut self, i: &ast::ViewItem) {
         match i.node {
-            ast::ViewItemUse(ref path) => {
-                if let ast::ViewPathGlob(..) = path.node {
-                    self.gate_feature("globs", path.span,
-                                      "glob import statements are \
-                                       experimental and possibly buggy");
-                }
-            }
+            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");
                     }
                 }
             }
@@ -294,7 +267,7 @@ fn visit_item(&mut self, i: &ast::Item) {
                 }
             }
 
-            ast::ItemImpl(_, polarity, _, _, _, ref items) => {
+            ast::ItemImpl(_, polarity, _, _, _, _) => {
                 match polarity {
                     ast::ImplPolarity::Negative => {
                         self.gate_feature("optin_builtin_traits",
@@ -314,16 +287,12 @@ fn visit_item(&mut self, i: &ast::Item) {
                                        removed in the future");
                 }
 
-                for item in items.iter() {
-                    match *item {
-                        ast::MethodImplItem(_) => {}
-                        ast::TypeImplItem(ref typedef) => {
-                            self.gate_feature("associated_types",
-                                              typedef.span,
-                                              "associated types are \
-                                               experimental")
-                        }
-                    }
+                if attr::contains_name(i.attrs[],
+                                       "old_orphan_check") {
+                    self.gate_feature(
+                        "old_orphan_check",
+                        i.span,
+                        "the new orphan check rules will eventually be strictly enforced");
                 }
             }
 
@@ -333,17 +302,6 @@ fn visit_item(&mut self, i: &ast::Item) {
         visit::walk_item(self, i);
     }
 
-    fn visit_trait_item(&mut self, trait_item: &ast::TraitItem) {
-        match *trait_item {
-            ast::RequiredMethod(_) | ast::ProvidedMethod(_) => {}
-            ast::TypeTraitItem(ref ti) => {
-                self.gate_feature("associated_types",
-                                  ti.ty_param.span,
-                                  "associated types are experimental")
-            }
-        }
-    }
-
     fn visit_foreign_item(&mut self, i: &ast::ForeignItem) {
         if attr::contains_name(i.attrs[], "linkage") {
             self.gate_feature("linkage", i.span,
@@ -379,20 +337,6 @@ fn visit_expr(&mut self, e: &ast::Expr) {
         visit::walk_expr(self, e);
     }
 
-    fn visit_generics(&mut self, generics: &ast::Generics) {
-        for type_parameter in generics.ty_params.iter() {
-            match type_parameter.default {
-                Some(ref ty) => {
-                    self.gate_feature("default_type_params", ty.span,
-                                      "default type parameters are \
-                                       experimental and possibly buggy");
-                }
-                None => {}
-            }
-        }
-        visit::walk_generics(self, generics);
-    }
-
     fn visit_attribute(&mut self, attr: &ast::Attribute) {
         if attr::contains_name(slice::ref_slice(attr), "lang") {
             self.gate_feature("lang_items",
@@ -498,7 +442,6 @@ fn check_crate_inner<F>(cm: &CodeMap, span_handler: &SpanHandler, krate: &ast::C
     check(&mut cx, krate);
 
     (Features {
-        default_type_params: cx.has_feature("default_type_params"),
         unboxed_closures: cx.has_feature("unboxed_closures"),
         rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
         import_shadowing: cx.has_feature("import_shadowing"),
index 396b0033b815fcc58dc9c837bf6e5415d302d8c7..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,
@@ -1257,7 +1261,7 @@ pub fn noop_fold_pat<T: Folder>(p: P<Pat>, folder: &mut T) -> P<Pat> {
             }
             PatTup(elts) => PatTup(elts.move_map(|x| folder.fold_pat(x))),
             PatBox(inner) => PatBox(folder.fold_pat(inner)),
-            PatRegion(inner) => PatRegion(folder.fold_pat(inner)),
+            PatRegion(inner, mutbl) => PatRegion(folder.fold_pat(inner), mutbl),
             PatRange(e1, e2) => {
                 PatRange(folder.fold_expr(e1), folder.fold_expr(e2))
             },
@@ -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 75b2c17b81bd487512fc8013d7380d2c86e15f66..a49680d7e1c0344a682098a6270ede9214650f4c 100644 (file)
@@ -13,8 +13,6 @@
 //!
 //! Obsolete syntax that becomes too hard to parse can be removed.
 
-pub use self::ObsoleteSyntax::*;
-
 use ast::{Expr, ExprTup};
 use codemap::Span;
 use parse::parser;
 /// The specific types of unsupported syntax
 #[derive(Copy, PartialEq, Eq, Hash)]
 pub enum ObsoleteSyntax {
-    ObsoleteOwnedType,
-    ObsoleteOwnedExpr,
-    ObsoleteOwnedPattern,
-    ObsoleteOwnedVector,
-    ObsoleteOwnedSelf,
-    ObsoleteImportRenaming,
-    ObsoleteSubsliceMatch,
-    ObsoleteExternCrateRenaming,
-    ObsoleteProcType,
-    ObsoleteProcExpr,
-    ObsoleteClosureType,
+    Sized,
+    ForSized,
+    OwnedType,
+    OwnedExpr,
+    OwnedPattern,
+    OwnedVector,
+    OwnedSelf,
+    ImportRenaming,
+    SubsliceMatch,
+    ExternCrateRenaming,
+    ProcType,
+    ProcExpr,
+    ClosureType,
 }
 
 pub trait ParserObsoleteMethods {
@@ -56,50 +56,59 @@ impl<'a> ParserObsoleteMethods for parser::Parser<'a> {
     /// Reports an obsolete syntax non-fatal error.
     fn obsolete(&mut self, sp: Span, kind: ObsoleteSyntax) {
         let (kind_str, desc) = match kind {
-            ObsoleteProcType => (
+            ObsoleteSyntax::ForSized => (
+                "for Sized?",
+                "no longer required. Traits (and their `Self` type) do not have the `Sized` bound \
+                 by default",
+            ),
+            ObsoleteSyntax::ProcType => (
                 "the `proc` type",
                 "use unboxed closures instead",
             ),
-            ObsoleteProcExpr => (
+            ObsoleteSyntax::ProcExpr => (
                 "`proc` expression",
                 "use a `move ||` expression instead",
             ),
-            ObsoleteOwnedType => (
+            ObsoleteSyntax::OwnedType => (
                 "`~` notation for owned pointers",
                 "use `Box<T>` in `std::owned` instead"
             ),
-            ObsoleteOwnedExpr => (
+            ObsoleteSyntax::OwnedExpr => (
                 "`~` notation for owned pointer allocation",
                 "use the `box` operator instead of `~`"
             ),
-            ObsoleteOwnedPattern => (
+            ObsoleteSyntax::OwnedPattern => (
                 "`~` notation for owned pointer patterns",
                 "use the `box` operator instead of `~`"
             ),
-            ObsoleteOwnedVector => (
+            ObsoleteSyntax::OwnedVector => (
                 "`~[T]` is no longer a type",
                 "use the `Vec` type instead"
             ),
-            ObsoleteOwnedSelf => (
+            ObsoleteSyntax::OwnedSelf => (
                 "`~self` is no longer supported",
                 "write `self: Box<Self>` instead"
             ),
-            ObsoleteImportRenaming => (
+            ObsoleteSyntax::ImportRenaming => (
                 "`use foo = bar` syntax",
                 "write `use bar as foo` instead"
             ),
-            ObsoleteSubsliceMatch => (
+            ObsoleteSyntax::SubsliceMatch => (
                 "subslice match syntax",
                 "instead of `..xs`, write `xs..` in a pattern"
             ),
-            ObsoleteExternCrateRenaming => (
+            ObsoleteSyntax::ExternCrateRenaming => (
                 "`extern crate foo = bar` syntax",
                 "write `extern crate bar as foo` instead"
             ),
-            ObsoleteClosureType => (
+            ObsoleteSyntax::ClosureType => (
                 "`|uint| -> bool` closure type syntax",
                 "use unboxed closures instead, no type annotation needed"
-            )
+            ),
+            ObsoleteSyntax::Sized => (
+                "`Sized? T` syntax for removing the `Sized` bound",
+                "write `T: ?Sized` instead"
+            ),
         };
 
         self.report(sp, kind, kind_str, desc);
index 28c7293fc26a33b4d8ab59ee355680cada72841e..32f8f5ee3d63b97c35aa94e14070129269204dac 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;
@@ -1155,7 +1153,7 @@ pub fn parse_proc_type(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> Ty_ {
         let _ = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Bare);
         let _ = self.parse_ret_ty();
 
-        self.obsolete(proc_span, ObsoleteProcType);
+        self.obsolete(proc_span, ObsoleteSyntax::ProcType);
 
         TyInfer
     }
@@ -1246,7 +1244,7 @@ pub fn parse_ty_closure(&mut self, lifetime_defs: Vec<ast::LifetimeDef>) -> Ty_
 
         let _ = self.parse_ret_ty();
 
-        self.obsolete(ty_closure_span, ObsoleteClosureType);
+        self.obsolete(ty_closure_span, ObsoleteSyntax::ClosureType);
 
         TyInfer
     }
@@ -1511,8 +1509,10 @@ pub fn parse_ty(&mut self) -> P<Ty> {
             self.bump();
             let last_span = self.last_span;
             match self.token {
-                token::OpenDelim(token::Bracket) => self.obsolete(last_span, ObsoleteOwnedVector),
-                _ => self.obsolete(last_span, ObsoleteOwnedType)
+                token::OpenDelim(token::Bracket) => {
+                    self.obsolete(last_span, ObsoleteSyntax::OwnedVector)
+                }
+                _ => self.obsolete(last_span, ObsoleteSyntax::OwnedType)
             }
             TyTup(vec![self.parse_ty()])
         } else if self.check(&token::BinOp(token::Star)) {
@@ -2275,7 +2275,7 @@ pub fn parse_bottom_expr(&mut self) -> P<Expr> {
                     let span = self.last_span;
                     let _ = self.parse_proc_decl();
                     let _ = self.parse_expr();
-                    return self.obsolete_expr(span, ObsoleteProcExpr);
+                    return self.obsolete_expr(span, ObsoleteSyntax::ProcExpr);
                 }
                 if self.eat_keyword(keywords::If) {
                     return self.parse_if_expr();
@@ -2737,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 };
@@ -2850,9 +2853,9 @@ pub fn parse_prefix_expr(&mut self) -> P<Expr> {
             let last_span = self.last_span;
             match self.token {
                 token::OpenDelim(token::Bracket) => {
-                    self.obsolete(last_span, ObsoleteOwnedVector)
+                    self.obsolete(last_span, ObsoleteSyntax::OwnedVector)
                 },
-                _ => self.obsolete(last_span, ObsoleteOwnedExpr)
+                _ => self.obsolete(last_span, ObsoleteSyntax::OwnedExpr)
             }
 
             let e = self.parse_prefix_expr();
@@ -2966,14 +2969,17 @@ pub fn parse_more_binops(&mut self, lhs: P<Expr>, min_prec: uint) -> P<Expr> {
     /// actually, this seems to be the main entry point for
     /// parsing an arbitrary expression.
     pub fn parse_assign_expr(&mut self) -> P<Expr> {
-        let lo = self.span.lo;
         let lhs = self.parse_binops();
+        self.parse_assign_expr_with(lhs)
+    }
+
+    pub fn parse_assign_expr_with(&mut self, lhs: P<Expr>) -> P<Expr> {
         let restrictions = self.restrictions & RESTRICTION_NO_STRUCT_LITERAL;
         match self.token {
           token::Eq => {
               self.bump();
               let rhs = self.parse_expr_res(restrictions);
-              self.mk_expr(lo, rhs.span.hi, ExprAssign(lhs, rhs))
+              self.mk_expr(lhs.span.lo, rhs.span.hi, ExprAssign(lhs, rhs))
           }
           token::BinOpEq(op) => {
               self.bump();
@@ -2991,8 +2997,9 @@ pub fn parse_assign_expr(&mut self) -> P<Expr> {
                   token::Shr =>     BiShr
               };
               let rhs_span = rhs.span;
+              let span = lhs.span;
               let assign_op = self.mk_assign_op(aop, lhs, rhs);
-              self.mk_expr(lo, rhs_span.hi, assign_op)
+              self.mk_expr(span.lo, rhs_span.hi, assign_op)
           }
           _ => {
               lhs
@@ -3223,7 +3230,7 @@ fn parse_pat_vec_elements(
                     } else {
                         let _ = self.parse_pat();
                         let span = self.span;
-                        self.obsolete(span, ObsoleteSubsliceMatch);
+                        self.obsolete(span, ObsoleteSyntax::SubsliceMatch);
                     }
                     continue
                 }
@@ -3339,7 +3346,7 @@ pub fn parse_pat(&mut self) -> P<Pat> {
             pat = PatBox(sub);
             let last_span = self.last_span;
             hi = last_span.hi;
-            self.obsolete(last_span, ObsoleteOwnedPattern);
+            self.obsolete(last_span, ObsoleteSyntax::OwnedPattern);
             return P(ast::Pat {
                 id: ast::DUMMY_NODE_ID,
                 node: pat,
@@ -3347,11 +3354,16 @@ pub fn parse_pat(&mut self) -> P<Pat> {
             })
           }
           token::BinOp(token::And) | token::AndAnd => {
-            // parse &pat
+            // parse &pat and &mut pat
             let lo = self.span.lo;
             self.expect_and();
+            let mutability = if self.eat_keyword(keywords::Mut) {
+                ast::MutMutable
+            } else {
+                ast::MutImmutable
+            };
             let sub = self.parse_pat();
-            pat = PatRegion(sub);
+            pat = PatRegion(sub, mutability);
             hi = self.last_span.hi;
             return P(ast::Pat {
                 id: ast::DUMMY_NODE_ID,
@@ -3870,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,
                                     }));
@@ -3885,9 +3897,10 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
                                 _ => {
                                     let e = self.mk_mac_expr(span.lo,
                                                              span.hi,
-                                                             macro.and_then(|m| m.node));
-                                    let e =
-                                        self.parse_dot_or_call_expr_with(e);
+                                                             mac.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);
                                     self.handle_expression_like_statement(
                                         e,
                                         ast::DUMMY_NODE_ID,
@@ -4080,8 +4093,8 @@ fn parse_ty_param(&mut self) -> TyParam {
         // unbound, and it may only be `Sized`. To avoid backtracking and other
         // complications, we parse an ident, then check for `?`. If we find it,
         // we use the ident as the unbound, otherwise, we use it as the name of
-        // type param. Even worse, for now, we need to check for `?` before or
-        // after the bound.
+        // type param. Even worse, we need to check for `?` before or after the
+        // bound.
         let mut span = self.span;
         let mut ident = self.parse_ident();
         let mut unbound = None;
@@ -4090,6 +4103,7 @@ fn parse_ty_param(&mut self) -> TyParam {
             unbound = Some(tref);
             span = self.span;
             ident = self.parse_ident();
+            self.obsolete(span, ObsoleteSyntax::Sized);
         }
 
         let mut bounds = self.parse_colon_then_ty_param_bounds(BoundParsingMode::Modified);
@@ -4453,7 +4467,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                     self.bump();
                     drop(self.expect_self_ident());
                     let last_span = self.last_span;
-                    self.obsolete(last_span, ObsoleteOwnedSelf)
+                    self.obsolete(last_span, ObsoleteSyntax::OwnedSelf)
                 }
                 SelfStatic
             }
@@ -4504,7 +4518,7 @@ fn maybe_parse_borrowed_explicit_self(this: &mut Parser)
                     self.bump();
                     drop(self.expect_self_ident());
                     let last_span = self.last_span;
-                    self.obsolete(last_span, ObsoleteOwnedSelf);
+                    self.obsolete(last_span, ObsoleteSyntax::OwnedSelf);
                     SelfStatic
                 } else {
                     SelfStatic
@@ -4880,67 +4894,116 @@ fn parse_item_struct(&mut self) -> ItemInfo {
             self.span_err(ty.span, "`virtual` structs have been removed from the language");
         }
 
-        self.parse_where_clause(&mut generics);
+        // There is a special case worth noting here, as reported in issue #17904.
+        // If we are parsing a tuple struct it is the case that the where clause
+        // should follow the field list. Like so:
+        //
+        // struct Foo<T>(T) where T: Copy;
+        //
+        // If we are parsing a normal record-style struct it is the case
+        // that the where clause comes before the body, and after the generics.
+        // So if we look ahead and see a brace or a where-clause we begin
+        // parsing a record style struct.
+        //
+        // Otherwise if we look ahead and see a paren we parse a tuple-style
+        // struct.
+
+        let (fields, ctor_id) = if self.token.is_keyword(keywords::Where) {
+            self.parse_where_clause(&mut generics);
+            if self.eat(&token::Semi) {
+                // If we see a: `struct Foo<T> where T: Copy;` style decl.
+                (Vec::new(), Some(ast::DUMMY_NODE_ID))
+            } else {
+                // If we see: `struct Foo<T> where T: Copy { ... }`
+                (self.parse_record_struct_body(&class_name), None)
+            }
+        // No `where` so: `struct Foo<T>;`
+        } else if self.eat(&token::Semi) {
+            (Vec::new(), Some(ast::DUMMY_NODE_ID))
+        // Record-style struct definition
+        } else if self.token == token::OpenDelim(token::Brace) {
+            let fields = self.parse_record_struct_body(&class_name);
+            (fields, None)
+        // Tuple-style struct definition with optional where-clause.
+        } else {
+            let fields = self.parse_tuple_struct_body(&class_name, &mut generics);
+            (fields, Some(ast::DUMMY_NODE_ID))
+        };
 
-        let mut fields: Vec<StructField>;
-        let is_tuple_like;
+        (class_name,
+         ItemStruct(P(ast::StructDef {
+             fields: fields,
+             ctor_id: ctor_id,
+         }), generics),
+         None)
+    }
 
+    pub fn parse_record_struct_body(&mut self, class_name: &ast::Ident) -> Vec<StructField> {
+        let mut fields = Vec::new();
         if self.eat(&token::OpenDelim(token::Brace)) {
-            // It's a record-like struct.
-            is_tuple_like = false;
-            fields = Vec::new();
             while self.token != token::CloseDelim(token::Brace) {
                 fields.push(self.parse_struct_decl_field(true));
             }
+
             if fields.len() == 0 {
                 self.fatal(format!("unit-like struct definition should be \
-                                    written as `struct {};`",
-                                   token::get_ident(class_name))[]);
+                    written as `struct {};`",
+                    token::get_ident(class_name.clone()))[]);
             }
+
             self.bump();
-        } else if self.check(&token::OpenDelim(token::Paren)) {
-            // It's a tuple-like struct.
-            is_tuple_like = true;
-            fields = self.parse_unspanned_seq(
+        } else {
+            let token_str = self.this_token_to_string();
+            self.fatal(format!("expected `where`, or `{}` after struct \
+                                name, found `{}`", "{",
+                                token_str)[]);
+        }
+
+        fields
+    }
+
+    pub fn parse_tuple_struct_body(&mut self,
+                                   class_name: &ast::Ident,
+                                   generics: &mut ast::Generics)
+                                   -> Vec<StructField> {
+        // This is the case where we find `struct Foo<T>(T) where T: Copy;`
+        if self.check(&token::OpenDelim(token::Paren)) {
+            let fields = self.parse_unspanned_seq(
                 &token::OpenDelim(token::Paren),
                 &token::CloseDelim(token::Paren),
                 seq_sep_trailing_allowed(token::Comma),
                 |p| {
-                let attrs = p.parse_outer_attributes();
-                let lo = p.span.lo;
-                let struct_field_ = ast::StructField_ {
-                    kind: UnnamedField(p.parse_visibility()),
-                    id: ast::DUMMY_NODE_ID,
-                    ty: p.parse_ty_sum(),
-                    attrs: attrs,
-                };
-                spanned(lo, p.span.hi, struct_field_)
-            });
+                    let attrs = p.parse_outer_attributes();
+                    let lo = p.span.lo;
+                    let struct_field_ = ast::StructField_ {
+                        kind: UnnamedField(p.parse_visibility()),
+                        id: ast::DUMMY_NODE_ID,
+                        ty: p.parse_ty_sum(),
+                        attrs: attrs,
+                    };
+                    spanned(lo, p.span.hi, struct_field_)
+                });
+
             if fields.len() == 0 {
                 self.fatal(format!("unit-like struct definition should be \
-                                    written as `struct {};`",
-                                   token::get_ident(class_name))[]);
+                    written as `struct {};`",
+                    token::get_ident(class_name.clone()))[]);
             }
+
+            self.parse_where_clause(generics);
             self.expect(&token::Semi);
-        } else if self.eat(&token::Semi) {
-            // It's a unit-like struct.
-            is_tuple_like = true;
-            fields = Vec::new();
+            fields
+        // This is the case where we just see struct Foo<T> where T: Copy;
+        } else if self.token.is_keyword(keywords::Where) {
+            self.parse_where_clause(generics);
+            self.expect(&token::Semi);
+            Vec::new()
+        // This case is where we see: `struct Foo<T>;`
         } else {
             let token_str = self.this_token_to_string();
-            self.fatal(format!("expected `{}`, `(`, or `;` after struct \
-                                name, found `{}`", "{",
-                               token_str)[])
+            self.fatal(format!("expected `where`, `{}`, `(`, or `;` after struct \
+                name, found `{}`", "{", token_str)[]);
         }
-
-        let _ = ast::DUMMY_NODE_ID;  // FIXME: Workaround for crazy bug.
-        let new_id = ast::DUMMY_NODE_ID;
-        (class_name,
-         ItemStruct(P(ast::StructDef {
-             fields: fields,
-             ctor_id: if is_tuple_like { Some(new_id) } else { None },
-         }), generics),
-         None)
     }
 
     /// Parse a structure field declaration
@@ -4993,6 +5056,7 @@ fn parse_for_sized(&mut self) -> Option<ast::TraitRef> {
         // re-jigged shortly in any case, so leaving the hacky version for now.
         if self.eat_keyword(keywords::For) {
             let span = self.span;
+
             let mut ate_question = false;
             if self.eat(&token::Question) {
                 ate_question = true;
@@ -5010,8 +5074,11 @@ fn parse_for_sized(&mut self) -> Option<ast::TraitRef> {
                     "expected `?Sized` after `for` in trait item");
                 return None;
             }
-            let tref = Parser::trait_ref_from_ident(ident, span);
-            Some(tref)
+            let _tref = Parser::trait_ref_from_ident(ident, span);
+
+            self.obsolete(span, ObsoleteSyntax::ForSized);
+
+            None
         } else {
             None
         }
@@ -5333,7 +5400,7 @@ fn parse_item_extern_crate(&mut self,
                     self.bump();
                     let path = self.parse_str();
                     let span = self.span;
-                    self.obsolete(span, ObsoleteExternCrateRenaming);
+                    self.obsolete(span, ObsoleteSyntax::ExternCrateRenaming);
                     Some(path)
                 } else if self.eat_keyword(keywords::As) {
                     // skip the ident if there is one
@@ -5960,6 +6027,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(
@@ -5990,7 +6061,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
                 path.push(id);
             }
             let span = mk_sp(path_lo, self.span.hi);
-            self.obsolete(span, ObsoleteImportRenaming);
+            self.obsolete(span, ObsoleteSyntax::ImportRenaming);
             let path = ast::Path {
                 span: span,
                 global: false,
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 e44cc2257c24c990a1915baf26d08d5dd29c7f4b..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),
@@ -1056,7 +1058,6 @@ pub fn print_struct(&mut self,
                         span: codemap::Span) -> IoResult<()> {
         try!(self.print_ident(ident));
         try!(self.print_generics(generics));
-        try!(self.print_where_clause(generics));
         if ast_util::struct_def_is_tuple_like(struct_def) {
             if !struct_def.fields.is_empty() {
                 try!(self.popen());
@@ -1075,10 +1076,12 @@ pub fn print_struct(&mut self,
                 ));
                 try!(self.pclose());
             }
+            try!(self.print_where_clause(generics));
             try!(word(&mut self.s, ";"));
             try!(self.end());
             self.end() // close the outer-box
         } else {
+            try!(self.print_where_clause(generics));
             try!(self.nbsp());
             try!(self.bopen());
             try!(self.hardbreak_if_not_bol());
@@ -2081,8 +2084,11 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
                 try!(word(&mut self.s, "box "));
                 try!(self.print_pat(&**inner));
             }
-            ast::PatRegion(ref inner) => {
+            ast::PatRegion(ref inner, mutbl) => {
                 try!(word(&mut self.s, "&"));
+                if mutbl == ast::MutMutable {
+                    try!(word(&mut self.s, "mut "));
+                }
                 try!(self.print_pat(&**inner));
             }
             ast::PatLit(ref e) => try!(self.print_expr(&**e)),
index 354ba854b101aa7906f2d9131d8aa3c9a4134ba3..57520257fe1b3f9e54fe61f4e7ac363e8b082f1e 100644 (file)
 //! This module shows spans for all expressions in the crate
 //! to help with compiler debugging.
 
+use std::str::FromStr;
+
 use ast;
 use diagnostic;
 use visit;
 use visit::Visitor;
 
+enum Mode {
+    Expression,
+    Pattern,
+    Type,
+}
+
+impl FromStr for Mode {
+    fn from_str(s: &str) -> Option<Mode> {
+        let mode = match s {
+            "expr" => Mode::Expression,
+            "pat" => Mode::Pattern,
+            "ty" => Mode::Type,
+            _ => return None
+        };
+        Some(mode)
+    }
+}
+
 struct ShowSpanVisitor<'a> {
     span_diagnostic: &'a diagnostic::SpanHandler,
+    mode: Mode,
 }
 
 impl<'a, 'v> Visitor<'v> for ShowSpanVisitor<'a> {
     fn visit_expr(&mut self, e: &ast::Expr) {
-        self.span_diagnostic.span_note(e.span, "expression");
+        if let Mode::Expression = self.mode {
+            self.span_diagnostic.span_note(e.span, "expression");
+        }
         visit::walk_expr(self, e);
     }
 
-    fn visit_mac(&mut self, macro: &ast::Mac) {
-        visit::walk_mac(self, macro);
+    fn visit_pat(&mut self, p: &ast::Pat) {
+        if let Mode::Pattern = self.mode {
+            self.span_diagnostic.span_note(p.span, "pattern");
+        }
+        visit::walk_pat(self, p);
+    }
+
+    fn visit_ty(&mut self, t: &ast::Ty) {
+        if let Mode::Type = self.mode {
+            self.span_diagnostic.span_note(t.span, "type");
+        }
+        visit::walk_ty(self, t);
+    }
+
+    fn visit_mac(&mut self, mac: &ast::Mac) {
+        visit::walk_mac(self, mac);
     }
 }
 
-pub fn run(span_diagnostic: &diagnostic::SpanHandler, krate: &ast::Crate) {
-    let mut v = ShowSpanVisitor { span_diagnostic: span_diagnostic };
+pub fn run(span_diagnostic: &diagnostic::SpanHandler,
+           mode: &str,
+           krate: &ast::Crate) {
+    let mode = match mode.parse() {
+        Some(mode) => mode,
+        None => return
+    };
+    let mut v = ShowSpanVisitor {
+        span_diagnostic: span_diagnostic,
+        mode: mode,
+    };
     visit::walk_crate(&mut v, krate);
 }
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 5f416a867e8bdb892e4b299f52ba6b9a03036dd0..85eea2d9daf27226f889f7c80b4c3643587fbd48 100644 (file)
@@ -77,7 +77,7 @@ pub fn len(&self) -> uint {
         (*vect).len()
     }
 
-    pub fn find<Sized? Q>(&self, val: &Q) -> Option<Name>
+    pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
     where Q: BorrowFrom<T> + Eq + Hash {
         let map = self.map.borrow();
         match (*map).get(val) {
@@ -202,7 +202,7 @@ pub fn len(&self) -> uint {
         self.vect.borrow().len()
     }
 
-    pub fn find<Sized? Q>(&self, val: &Q) -> Option<Name>
+    pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
     where Q: BorrowFrom<RcStr> + Eq + Hash {
         match (*self.map.borrow()).get(val) {
             Some(v) => Some(*v),
index 737f1b73b32907eba034eb585e9ae33e6c278288..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);
@@ -511,7 +511,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) {
             }
         }
         PatBox(ref subpattern) |
-        PatRegion(ref subpattern) => {
+        PatRegion(ref subpattern, _) => {
             visitor.visit_pat(&**subpattern)
         }
         PatIdent(_, ref pth1, ref optional_subpattern) => {
@@ -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 7e7f36f6e83fae1dbdf79b71caeffea8ff3b522b..8daabf610102256d86e1e86d8fb754977e1830a7 100644 (file)
@@ -39,7 +39,7 @@ fn local_sort<T: Float>(v: &mut [T]) {
 }
 
 /// Trait that provides simple descriptive statistics on a univariate set of numeric samples.
-pub trait Stats <T: FloatMath + FromPrimitive> for Sized? {
+pub trait Stats <T: FloatMath + FromPrimitive> {
 
     /// Sum of the samples.
     ///
@@ -169,7 +169,8 @@ impl<T: FloatMath + FromPrimitive> Stats<T> for [T] {
     fn sum(&self) -> T {
         let mut partials = vec![];
 
-        for &mut x in self.iter() {
+        for &x in self.iter() {
+            let mut x = x;
             let mut j = 0;
             // This inner loop applies `hi`/`lo` summation to each
             // partial so that the list of partial sums remains exact.
index 90949437774f107c3f1aa463af994ed7f2ce9170..13672a7b480af93459e372794e112c1755d75ab8 100644 (file)
@@ -37,7 +37,7 @@ pub struct Words<'a> {
 
 /// Methods for Unicode string slices
 #[allow(missing_docs)] // docs in libcollections
-pub trait UnicodeStr for Sized? {
+pub trait UnicodeStr {
     fn graphemes<'a>(&'a self, is_extended: bool) -> Graphemes<'a>;
     fn grapheme_indices<'a>(&'a self, is_extended: bool) -> GraphemeIndices<'a>;
     fn words<'a>(&'a self) -> Words<'a>;
index ec1fdb3b9d3b1fb9e1dae97a65dd3a13db9bfb23..b820135911e17c7a46b901db56baa48e5155bf46 160000 (submodule)
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit ec1fdb3b9d3b1fb9e1dae97a65dd3a13db9bfb23
+Subproject commit b820135911e17c7a46b901db56baa48e5155bf46
index c1ad6754ca1c36e877c5264f4448b291aca2dd9b..2ac855681f28b9970b1b95e770552532a30149c5 100644 (file)
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2015-01-03
+2015-01-05
index 17b2a0751fe297665062595ad17cdfcbf7286aa5..44fbcf2150a4bf9050ad727622351f4806cd10d4 100644 (file)
@@ -12,7 +12,6 @@
 // cross-crate scenario.
 
 #![crate_type="lib"]
-#![feature(associated_types)]
 
 pub trait Bar {
     type T;
index 0e0a206500821c369103f51be3117514eb5b521a..d12f716decf9925dfe4e53cb1e58f034dab283f8 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 pub struct Heap;
 
 pub struct FakeHeap;
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 41572998b58a418ed213fb98e9761f1d629ffdde..c3f7f2d1aa1666ede0d3c29d0e33584c5cbc7f46 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![crate_type = "lib"]
-#![feature(associated_types)]
 
 pub struct TreeBuilder<H>;
 
index 60e3cb13e2e46a88a4d1b0693feec04b212f5db2..7a378b06df9e175ceac52066671a93b94ce8825e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 pub trait T {
     type C;
 }
index 8a9fa4dbc4adfd2d5eb112ff34e4f4a0417470f0..8a212f6e5a9c5050b055fa29cd6fd0cd9e87f992 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![allow(unused_imports)]
-#![feature(globs)]
 
 extern crate issue_2316_a;
 
index e6bae4628874c46b5ad0daf800589b32835786a0..e99a8f0b8773750c9e9ec77130b6a9c2bf2be8c6 100644 (file)
@@ -12,7 +12,7 @@
 #![feature(lang_items)]
 
 #[lang="sized"]
-pub trait Sized for Sized? {}
+pub trait Sized {}
 
 #[lang="panic"]
 fn panic(_: &(&'static str, &'static str, uint)) -> ! { loop {} }
index 0b4bea49fa2499d0481dbdcbe5178c20c8401fe9..6cd94ee5602aa5ccf3db96b0b1f3ccda3dcae6ef 100644 (file)
@@ -27,7 +27,7 @@ fn bar() { }
 fn baz() { }
 
 pub fn test() {
-    let none: Option<Path> = None; // appease the typechecker
+    let none: Option<&Path> = None; // appease the typechecker
     let lib = DynamicLibrary::open(none).unwrap();
     unsafe {
         assert!(lib.symbol::<int>("foo").is_ok());
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 b82cfcbc8fcb297685a3e5b9e73de1a646b957d6..99f02cf2d58ba02ca15d5f74e348ea2d8a1fd51c 100644 (file)
@@ -10,7 +10,7 @@
 
 // force-host
 
-#![feature(globs, 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;
index c7387dd284ebf3537cb4f1d2db7be36d6f79ebf6..7412c17fd45b28cf3b32854f39f94866ff241bcd 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.
-#![feature(globs)]
 
 pub use Foo::*;
 
@@ -34,5 +33,3 @@ impl Bar {
         pub fn foo() {}
     }
 }
-
-
index 05960a5b8e1dd6196a51f865972be9c745200433..caa9bbe5736e4adb55d0c7620dfe996b0feef5dc 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
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 {
index 88548bb5410e6d36420c246718ea80ddee2611a9..5ad1d244c926d378875b8a1b2e27bc38bcffd8ea 100644 (file)
@@ -11,7 +11,7 @@
 // force-host
 
 #![crate_type = "dylib"]
-#![feature(plugin_registrar, quote, globs)]
+#![feature(plugin_registrar, quote)]
 
 extern crate "syntax-extension-with-dll-deps-1" as other;
 extern crate syntax;
index 7394373e9229bb61d5b58befd0b4ea96d590dc51..cbd2ac69c789415114f21ea2408fb8eae84d8ac8 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::cmp::PartialEq;
 use std::ops::{Add, Sub, Mul};
 
index fd454509b394055aed33f8e44e70ad0d1cb0193b..33824af6187a2ff6757d379737ff7c13600cfc4f 100644 (file)
@@ -10,7 +10,7 @@
 
 // Test inherant trait impls work cross-crait.
 
-pub trait Bar<'a> for ?Sized : 'a {}
+pub trait Bar<'a> : 'a {}
 
 impl<'a> Bar<'a> {
     pub fn bar(&self) {}
diff --git a/src/test/auxiliary/two_macros.rs b/src/test/auxiliary/two_macros.rs
new file mode 100644 (file)
index 0000000..060960f
--- /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_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 adf773a2f252cf723b72bf6f03f7b3ddc4fc3107..5ecc580de08d554ca1c7c49ffa62f25e46c9a055 100644 (file)
@@ -35,21 +35,24 @@ fn run_pair(n: uint) {
         // Create a channel: B->A
         let (btx, brx) = channel();
 
-        Thread::spawn(move|| {
+        let guard_a = Thread::spawn(move|| {
             let (tx, rx) = (atx, brx);
             for _ in range(0, n) {
                 tx.send(()).unwrap();
                 rx.recv().unwrap();
             }
-        }).detach();
+        });
 
-        Thread::spawn(move|| {
+        let guard_b = Thread::spawn(move|| {
             let (tx, rx) = (btx, arx);
             for _ in range(0, n) {
                 rx.recv().unwrap();
                 tx.send(()).unwrap();
             }
-        }).detach();
+        });
+
+        guard_a.join().ok();
+        guard_b.join().ok();
     }
 
     for _ in range(0, m) {
index 8777fa9689f94778b195373810aacc32b2e320f5..9128930651f25ec6fd77ea6a1a7821ca214ba09b 100644 (file)
@@ -38,7 +38,7 @@
 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 // OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#![feature(associated_types, slicing_syntax)]
+#![feature(slicing_syntax)]
 
 use std::cmp::min;
 use std::io::{BufferedWriter, File};
index 359f06d0cf5f9eb50b0a9996fd91f11502cb2986..28d7488c9bf8f837f3458d0d2f0d9b0d180a0c58 100644 (file)
@@ -40,7 +40,7 @@
 
 // ignore-android see #10393 #13206
 
-#![feature(associated_types, slicing_syntax)]
+#![feature(slicing_syntax)]
 
 use std::ascii::OwnedAsciiExt;
 use std::iter::repeat;
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 cdc7617fec8b074f294cd4117988b1a19e9b6557..ca3d10afa5d47e38ee02e001c62f916844cece64 100644 (file)
@@ -40,8 +40,6 @@
 
 // no-pretty-expanded FIXME #15189
 
-#![feature(associated_types)]
-
 use std::iter::repeat;
 use std::sync::Arc;
 use std::sync::mpsc::channel;
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;
 
index bbbd7aebd547538d61f875204bc3485f049e405b..77bae87c7dd219e01d674909604b5be9db8c9c68 100644 (file)
@@ -40,7 +40,7 @@
 
 // ignore-android see #10393 #13206
 
-#![feature(associated_types, slicing_syntax, unboxed_closures)]
+#![feature(slicing_syntax, unboxed_closures)]
 
 extern crate libc;
 
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 6555aa32027797cc32d91d78b4eebecf5f57b2a3..c55e24e81adc220c9759e9aef7e8feb0888a4940 100644 (file)
@@ -11,8 +11,6 @@
 // Test equality constraints in a where clause where the type being
 // equated appears in a supertrait.
 
-#![feature(associated_types)]
-
 pub trait Vehicle {
     type Color;
 
index 01f9bd3541fc58f53315ad95d7e87ecd619afe7f..abaf79fb4cb1bc6cfc440466379b0765cc144540 100644 (file)
@@ -11,8 +11,6 @@
 // Test equality constraints in a where clause where the type being
 // equated appears in a supertrait.
 
-#![feature(associated_types)]
-
 pub trait Vehicle {
     type Color;
 
index 5743216b6ca69e1ae98e757597f9dc3825a46b75..183781e9e241723c21b476f888e97536cbfcabb0 100644 (file)
 // just propagate the error.
 
 #![crate_type = "lib"]
-#![feature(associated_types, default_type_params, lang_items)]
+#![feature(lang_items)]
 #![no_std]
 
 #[lang="sized"]
-pub trait Sized for Sized? {
+pub trait Sized {
     // Empty.
 }
 
index a362529bee8e423f963af38915dd061958ab2985..b1194154911c98c2773891636d681d402509f102 100644 (file)
@@ -11,8 +11,6 @@
 // Test equality constraints in a where clause where the type being
 // equated appears in a supertrait.
 
-#![feature(associated_types)]
-
 pub trait Vehicle {
     type Color;
 
index 7981fe3182712609fc01df0e8dabbd5b7e3516af..918826bb390cbe8320a658faa63fb01cc84bfc9d 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test equality constraints on associated types in a where clause.
 
-#![feature(associated_types)]
-
 pub trait ToInt {
     fn to_int(&self) -> int;
 }
index e93d9db28cf4b18eb6e59168281a4e88cfe5f7df..58dbb9863254afd1419252f02b58943a571a4be3 100644 (file)
@@ -11,8 +11,6 @@
 // Test equality constraints on associated types. Check that unsupported syntax
 // does not ICE.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
index b89cdd8c0eed7c233ca1efc07385c85fdf382694..e298d05d11dad1baa4e49763b64ed886d4102f98 100644 (file)
@@ -11,8 +11,6 @@
 // Test equality constraints on associated types. Check we get an error when an
 // equality constraint is used in a qualified path.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
index e5974925d7370b6d813962e3cfa8858f6f08c6d6..0f18a84cd1ae317186030e7b9639379d31fe4bd8 100644 (file)
@@ -11,8 +11,6 @@
 // Test equality constraints on associated types. Check we get type errors
 // where we should.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
index 1a96b0ca6812e357b507e1daea4e8ffd69b5f8b8..ef56fdeb051835ce3965e9d062c973811cddf85d 100644 (file)
@@ -10,8 +10,6 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-#![feature(associated_types)]
-
 trait Foo {
     type A;
     fn bar() -> int;
index aad55745c25dfb9eceeeecff9073a1a860106f89..2532977b1ca24c021f87535c3d93736838d9ea12 100644 (file)
@@ -10,8 +10,6 @@
 
 // Check testing of equality constraints in a higher-ranked context.
 
-#![feature(associated_types)]
-
 pub trait TheTrait<T> {
     type A;
 
diff --git a/src/test/compile-fail/associated-types-feature-gate.rs b/src/test/compile-fail/associated-types-feature-gate.rs
deleted file mode 100644 (file)
index d95b94f..0000000
+++ /dev/null
@@ -1,33 +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.
-
-trait Get {
-    type Value; //~ ERROR associated types are experimental
-    fn get(&self) -> Get::Value;
-}
-
-struct Struct {
-    x: int,
-}
-
-impl Get for Struct {
-    type Value = int;   //~ ERROR associated types are experimental
-    fn get(&self) -> int {
-        self.x
-    }
-}
-
-fn main() {
-    let s = Struct {
-        x: 100,
-    };
-    assert_eq!(s.get(), 100);
-}
-
index 2c6ee502fca3ed115cb5bc34330825e3b5a18806..9c173515793f44f84c47038fb8a51f0de08e8aa6 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
     type Value;
     fn get(&self) -> <Self as Get>::Value;
@@ -22,4 +20,3 @@ fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
 
 fn main() {
 }
-
index fcd3e4d1636468379318c1529e6d177801126726..3999e9cbe753d1d90ab8294ada23d1d1be274f6a 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
     type Value;
     fn get(&self) -> <Self as Get>::Value;
@@ -26,4 +24,3 @@ trait Grab {
 
 fn main() {
 }
-
index 7e4e1315110af5e29281044b22111db0f1fe08d2..371f97e867a2976b9a149cff2917c348d79bc868 100644 (file)
@@ -11,8 +11,6 @@
 // Check that the user gets an errror if they omit a binding from an
 // object type.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
     type B;
diff --git a/src/test/compile-fail/associated-types-invalid-trait-ref-issue-18865.rs b/src/test/compile-fail/associated-types-invalid-trait-ref-issue-18865.rs
new file mode 100644 (file)
index 0000000..b04b83e
--- /dev/null
@@ -0,0 +1,24 @@
+// 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.
+
+// Test that we report an error if the trait ref in an qualified type
+// uses invalid type arguments.
+
+trait Foo<T> {
+    type Bar;
+    fn get_bar(&self) -> Self::Bar;
+}
+
+fn f<T:Foo<int>>(t: &T) {
+    let u: <T as Foo<uint>>::Bar = t.get_bar();
+    //~^ ERROR the trait `Foo<uint>` is not implemented for the type `T`
+}
+
+fn main() { }
diff --git a/src/test/compile-fail/associated-types-issue-17359.rs b/src/test/compile-fail/associated-types-issue-17359.rs
new file mode 100644 (file)
index 0000000..6c79105
--- /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.
+
+// Test that we do not ICE when an impl is missing an associated type (and that we report
+// a useful error, of course).
+
+trait Trait {
+    type Type;
+}
+
+impl Trait for int {}  //~ ERROR missing: `Type`
+
+fn main() {}
+
index e4364b12580d3a7476acca07e5954b3be0e2e08d..a00aa8364bde2adeed76ab24a99771fd61a49e2c 100644 (file)
@@ -11,7 +11,6 @@
 // Test that we reliably check the value of the associated type.
 
 #![crate_type = "lib"]
-#![feature(associated_types)]
 #![no_implicit_prelude]
 
 use std::option::Option::{self, None, Some};
index 6b856204091516dd47b31839ae9d46fccad15ed6..98f2355f9be1a40e109ffa72eeb4d7694876c071 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
     type Value;
     fn get(&self) -> <Self as Get>::Value;
@@ -26,4 +24,3 @@ fn uhoh<T>(foo: <T as Get>::Value) {}
 
 fn main() {
 }
-
index 5a4ebeac41eef0f3f5d47165b033a180fbfdf9cd..a3f2850b29464589d86e4c28f38112be3065f0f2 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 // Check that we get an error when you use `<Self as Get>::Value` in
 // the trait definition but `Self` does not, in fact, implement `Get`.
 
index 41f5bc17b561bb9ee378a3405ff3fc6f4c2fcb18..ab061ca4d8da62fcec0bcf48dccc22e5906168bd 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test that we have one and only one associated type per ref.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
 }
@@ -23,4 +21,3 @@ pub fn f1<T>(a: T, x: T::A) {} //~ERROR associated type `A` not found
 pub fn f2<T: Foo + Bar>(a: T, x: T::A) {} //~ERROR ambiguous associated type `A`
 
 pub fn main() {}
-
index 989214d81da9e508d87a3186f96cbb94c1c6616e..ef85fc22fe7d442808835d106899d4d229ff0fe2 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test type checking of uses of associated types via sugary paths.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
 }
index 1f0f044a4c0c390797287276d8aa36613bdac1be..c5245840c4285a34404cc83b348801b94640aaeb 100644 (file)
@@ -11,8 +11,6 @@
 // Test you can't use a higher-ranked trait bound inside of a qualified
 // path (just won't parse).
 
-#![feature(associated_types)]
-
 pub trait Foo<T> {
     type A;
 
index 0e13efdebc9558cc64f1436cd1390f71ab5231ea..1f1ab4ca4b6d86d6e8870de4c9eb75492d79238e 100644 (file)
@@ -11,8 +11,6 @@
 // Check projection of an associated type out of a higher-ranked
 // trait-bound in the context of a function body.
 
-#![feature(associated_types)]
-
 pub trait Foo<T> {
     type A;
 
index 0d5c69591423b8605414358a77a133aaa977b001..0920bfab32b97f20ad9267f91d5b8d1acf6a4496 100644 (file)
@@ -11,8 +11,6 @@
 // Check projection of an associated type out of a higher-ranked trait-bound
 // in the context of a function signature.
 
-#![feature(associated_types)]
-
 pub trait Foo<T> {
     type A;
 
index 5016c6448a50e7322eb2117526540e951c46900d..0acb0f4853bc201b5da3d8ac434494cd99a9e841 100644 (file)
@@ -11,8 +11,6 @@
 // Check projection of an associated type out of a higher-ranked trait-bound
 // in the context of a struct definition.
 
-#![feature(associated_types)]
-
 pub trait Foo<T> {
     type A;
 
index a92d4ec04cb20ca6bef96d2f2455f88831e0b6e5..21e92c53058d66b241aac2425cf8a31299571377 100644 (file)
@@ -11,8 +11,6 @@
 // Check projection of an associated type out of a higher-ranked trait-bound
 // in the context of a method definition in a trait.
 
-#![feature(associated_types)]
-
 pub trait Foo<T> {
     type A;
 
index 02e1121880678cdbf70d0308a17f9e53e9a3b068..968634669446a2cf0816fa0c082a64963c998fcd 100644 (file)
@@ -10,8 +10,6 @@
 
 // Check that an associated type cannot be bound in an expression path.
 
-#![feature(associated_types)]
-
 trait Foo {
     type A;
     fn bar() -> int;
index 47ab09d279f62ab773d6bca5051af0ca9c80c307..db39eafc1912bb5064679d2af3ec8fecb5a8b4cc 100644 (file)
@@ -8,10 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
-    type Sized? Value;
+    type Value: ?Sized;
     fn get(&self) -> <Self as Get>::Value;
 }
 
@@ -21,4 +19,3 @@ fn foo<T:Get>(t: T) {
 
 fn main() {
 }
-
index 930000e5f0c3746f3733440e8d301219305e5a44..c525a67c7e9f887a3bc1f8aca2e06c8050a614e1 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test that binary operators consume their arguments
 
-#![feature(associated_types, default_type_params)]
-
 use std::ops::{Add, Sub, Mul, Div, Rem, BitAnd, BitXor, BitOr, Shl, Shr};
 
 fn add<A: Add<B, Output=()>, B>(lhs: A, rhs: B) {
index e51ca6a70f28b9739c4414b0bf2037aaafa61740..ffc38cc0a6005557eb0f2c17214fb03005848aae 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test that move restrictions are enforced on overloaded binary operations
 
-#![feature(associated_types, default_type_params)]
-
 use std::ops::Add;
 
 fn double_move<T: Add<Output=()>>(x: T) {
index 7cd170f7773e9ced96363f891023624a3e35b265..66bcfc23808354d98635c3c004b9740bedc04ebe 100644 (file)
@@ -11,8 +11,6 @@
 // Test how overloaded deref interacts with borrows when DerefMut
 // is implemented.
 
-#![feature(associated_types)]
-
 use std::ops::{Deref, DerefMut};
 
 struct Own<T> {
index 759467aeda36e53e32a9780cef0f6c938cf3df0e..abab9e57ffe34e7c181b674070c6598859e8a3a5 100644 (file)
@@ -11,8 +11,6 @@
 // Test how overloaded deref interacts with borrows when only
 // Deref and not DerefMut is implemented.
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 struct Rc<T> {
index 74dceab18ea48b2c8d179c7482578d70d7d07383..dda7e4d10474b48838a575d1f33f2a3ed9282550 100644 (file)
@@ -11,8 +11,6 @@
 // Test how overloaded deref interacts with borrows when DerefMut
 // is implemented.
 
-#![feature(associated_types)]
-
 use std::ops::{Deref, DerefMut};
 
 struct Own<T> {
index 635e440c6fe120b1532a509ef1562fcbfee85449..001a5232b127fe05fb8d8c4366071806809d1166 100644 (file)
@@ -11,8 +11,6 @@
 // Test how overloaded deref interacts with borrows when only
 // Deref and not DerefMut is implemented.
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 struct Rc<T> {
index 141dd8905bece30cd99e8db1ecc7726d8e18598c..924d70e9f46c6c880ace78b9d48ec97cb8444516 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::Add;
 
 #[derive(Clone)]
index e0a961e5cc5fcd4ac7f2e4fa29fbc6bd4f1d2679..5aa2deb44f192b23f8dbf6851ad7f7f42982d1c7 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types, default_type_params)]
-
 use std::ops::Add;
 
 #[derive(Copy)]
index 87e647d16ddf84861910671b4391c30cb41d4647..53fb935755cf05e66010a12f45d7c1e9d86086f2 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::Index;
 
 struct MyVec<T> {
index e7bd7cdf0b79de2be624f24f04589d85aea334f1..416e67dac0ced8f8e2c1383bc663957c284b5b8f 100644 (file)
@@ -11,8 +11,6 @@
 // Test that we still see borrowck errors of various kinds when using
 // indexing and autoderef in combination.
 
-#![feature(associated_types)]
-
 use std::ops::{Index, IndexMut};
 
 struct Foo {
@@ -95,5 +93,3 @@ fn test9(mut f: Box<Bar>, g: Bar, s: String) {
 
 fn main() {
 }
-
-
index 532f32ce770a6bbe280ee2e051c626c32d9d96ee..80b68dbf519eefb62325a0f1383778e1a4d2cb9c 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::{Index, IndexMut};
 
 struct Foo {
@@ -70,5 +68,3 @@ fn main() {
     s[2] = 20;
     //~^ ERROR cannot assign to immutable dereference (dereference is implicit, due to indexing)
 }
-
-
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 67d96aa95a6a2513ba59bb831b1f3512c03a48e1..d88b8751ea7b02c495329b51a5a569a2924572ae 100644 (file)
@@ -14,6 +14,6 @@
 use lib::Remote;
 
 impl<T> Remote for int { }
-//~^ ERROR cannot provide an extension implementation
+//~^ ERROR E0117
 
 fn main() { }
diff --git a/src/test/compile-fail/coherence-bigint-int.rs b/src/test/compile-fail/coherence-bigint-int.rs
new file mode 100644 (file)
index 0000000..b4917d0
--- /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:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
+
+pub struct BigInt;
+
+impl Remote1<BigInt> for int { } //~ ERROR E0117
+
+fn main() { }
index a04dfd36c98f175e3acaac0f414785ac5cfa02be..b8e48436a4143d7bfbffcec87986c1de57de216d 100644 (file)
@@ -16,6 +16,6 @@
 pub struct BigInt;
 
 impl<T> Remote1<BigInt> for T { }
-//~^ ERROR type parameter `T` must also appear
+//~^ ERROR type parameter `T` is not constrained
 
 fn main() { }
diff --git a/src/test/compile-fail/coherence-bigint-vecint.rs b/src/test/compile-fail/coherence-bigint-vecint.rs
new file mode 100644 (file)
index 0000000..de4e656
--- /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:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
+
+pub struct BigInt;
+
+impl Remote1<BigInt> for Vec<int> { } //~ ERROR E0117
+
+fn main() { }
index 99446be43acaa7930caf30614581a0ce0d7f6328..8bdd5c58f31990d355fcacc950cad2b875045e87 100644 (file)
@@ -16,7 +16,7 @@
 use trait_impl_conflict::Foo;
 
 impl<A> Foo for A {
-    //~^ ERROR E0117
+    //~^ ERROR type parameter `A` is not constrained
     //~^^ ERROR E0119
 }
 
diff --git a/src/test/compile-fail/coherence-iterator-vec-any-elem.rs b/src/test/compile-fail/coherence-iterator-vec-any-elem.rs
deleted file mode 100644 (file)
index 2ed7a6d..0000000
+++ /dev/null
@@ -1,21 +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.
-
-// aux-build:coherence-lib.rs
-
-extern crate "coherence-lib" as lib;
-use lib::Remote1;
-
-struct Foo<T>(T);
-
-impl<T,U> Remote1<U> for Foo<T> { }
-//~^ ERROR type parameter `U` must also appear
-
-fn main() { }
index 0223dacd8eca0754761e73fa2a06fc448de8f730..917438722de4e9c01767325dc030e10bae7fee0d 100644 (file)
@@ -13,6 +13,6 @@
 extern crate "coherence-lib" as lib;
 use lib::Remote;
 
-impl<T> Remote for T { } //~ ERROR E0117
+impl<T> Remote for T { } //~ ERROR type parameter `T` is not constrained
 
 fn main() { }
index c44b0da5b154f32a49b57a9fce079aa479b2c0e1..30a382c143dab7cbe7b1242585c6da8cdb5943bc 100644 (file)
@@ -18,7 +18,7 @@
 
 impl TheTrait<uint> for int { } //~ ERROR E0117
 
-impl TheTrait<TheType> for int { }
+impl TheTrait<TheType> for int { } //~ ERROR E0117
 
 impl TheTrait<int> for TheType { }
 
index d42bd529b6665bd12cf12c801501b70eb21b0fc9..9354e66af0d81f5c4fc5dd95e1f169bf106505f9 100644 (file)
@@ -16,6 +16,6 @@
 struct Foo;
 
 impl<T> Remote for lib::Pair<T,Foo> { }
-//~^ ERROR type parameter `T` must also appear
+//~^ ERROR type parameter `T` is not constrained
 
 fn main() { }
index 09895ec11db108529a20fe7955904a574c3b8b77..92a07b35852920b8dbec7e6284adcd5bf60476c8 100644 (file)
@@ -16,6 +16,6 @@
 struct Local<T>(T);
 
 impl<T,U> Remote for Pair<T,Local<U>> { }
-//~^ ERROR type parameter `T` must also appear
+//~^ ERROR type parameter `T` is not constrained
 
 fn main() { }
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() {}
index 8304afa1141ee7b9701f9fbcf92c2d9eeb6debb2..238700254b8fd020096fd6121143f1acd5e8a0d0 100644 (file)
@@ -10,7 +10,7 @@
 
 impl Drop for int {
     //~^ ERROR the Drop trait may only be implemented on structures
-    //~^^ ERROR cannot provide an extension implementation
+    //~^^ ERROR E0117
     fn drop(&mut self) {
         println!("kaboom");
     }
index fcc08cfcb168035d9204374a1a10324713af80ff..5e360b6ab9bad8fa2d4e40dd5fbdc022bc7ee17b 100644 (file)
@@ -10,7 +10,7 @@
 
 // Forbid assignment into a dynamically sized type.
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     f1: int,
     f2: &'static str,
     ptr: T
index eb54f3f8e781fbcc38a7f3ec841e86d7cb3a16ab..cc709be99002ea2a35ca44d04f6c9823409a30fd 100644 (file)
@@ -10,7 +10,7 @@
 
 // Forbid assignment into a dynamically sized type.
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     f1: int,
     f2: &'static str,
     ptr: T
index c77ae25e0cf519db4ff4c5a8fa95d9dd8b054228..75bd94331b11d591b431c31d1872106fd2d839b9 100644 (file)
@@ -10,7 +10,7 @@
 
 // Attempt to change the type as well as unsizing.
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     ptr: T
 }
 
index 6eb650e97811786065d054b8e208b480126fbca5..54c625221ba7d0216270ca705c30179ec57b1450 100644 (file)
@@ -10,7 +10,7 @@
 
 // Attempt to change the mutability as well as unsizing.
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     ptr: T
 }
 
index b0bd517637464891a47ab5826900c13b325b9057..192d43e32fd27523dc43d60fb41dbe53a2eb55d3 100644 (file)
@@ -10,7 +10,7 @@
 
 // Attempt to extend the lifetime as well as unsizing.
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     ptr: T
 }
 
index 783a32d63028a9bb0492605e92b1938041c06c5c..53ce18c73a08845e011927466a983e99f822653e 100644 (file)
@@ -10,7 +10,7 @@
 
 // Attempt to coerce from unsized to sized.
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     ptr: T
 }
 
index c3a814e3f44ff12b7f5b093461fee4f70b00c9a4..b30eada162b84707134573888de917956f8ca50c 100644 (file)
@@ -14,7 +14,7 @@
 trait T {}
 impl T for S {}
 
-struct Foo<Sized? T> {
+struct Foo<T: ?Sized> {
     f: T
 }
 
index 0833a74f1daf95f40033f642d8200e02b79ceefa..b169824cb3aca2e40a44473aca31a23bee64e319 100644 (file)
@@ -13,7 +13,7 @@
 // because it would require stack allocation of an unsized temporary (*g in the
 // test).
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     ptr: T
 }
 
index 06d20c3361bc96e17c2d2e16383eeac183cc69e9..e297ecaac233e49da769b1e22cde3f875ce57f6d 100644 (file)
@@ -11,8 +11,6 @@
 // Test that overloaded index expressions with DST result types
 // can't be used as rvalues
 
-#![feature(associated_types)]
-
 use std::ops::Index;
 use std::fmt::Show;
 
index 99c63c3c6e95e01c0b4f7e68f96997a670333864..3c75b5b6eddb8b77cacbd767680f76ddb01c546b 100644 (file)
 
 // Test that we cannot create objects from unsized types.
 
-trait Foo for Sized? {}
+trait Foo {}
 impl Foo for str {}
 
-fn test1<Sized? T: Foo>(t: &T) {
+fn test1<T: ?Sized + Foo>(t: &T) {
     let u: &Foo = t;
     //~^ ERROR `core::kinds::Sized` is not implemented for the type `T`
 }
 
-fn test2<Sized? T: Foo>(t: &T) {
+fn test2<T: ?Sized + Foo>(t: &T) {
     let v: &Foo = t as &Foo;
     //~^ ERROR `core::kinds::Sized` is not implemented for the type `T`
 }
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-default-type-param-usage.rs b/src/test/compile-fail/gated-default-type-param-usage.rs
deleted file mode 100644 (file)
index 4c8b5de..0000000
+++ /dev/null
@@ -1,22 +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.
-
-// aux-build:default_type_params_xc.rs
-
-#![deny(default_type_param_usage)]
-
-extern crate default_type_params_xc;
-
-pub struct FooAlloc;
-
-pub type VecFoo<T> = default_type_params_xc::FakeVec<T, FooAlloc>;
-//~^ ERROR: default type parameters are experimental
-
-fn main() {}
diff --git a/src/test/compile-fail/gated-default-type-params.rs b/src/test/compile-fail/gated-default-type-params.rs
deleted file mode 100644 (file)
index 65575d4..0000000
+++ /dev/null
@@ -1,15 +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.
-
-struct Heap;
-
-struct Vec<T, A = Heap>; //~ ERROR: default type parameters are experimental
-
-fn main() {}
diff --git a/src/test/compile-fail/gated-glob-imports.rs b/src/test/compile-fail/gated-glob-imports.rs
deleted file mode 100644 (file)
index cc7ba78..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.
-
-use std::*;
-//~^ ERROR: glob import statements are experimental
-
-fn main() {}
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 7e7eee3cfaca86d58ab0ae49c52afd7fb4ae7016..a8b1911426c42dbeb498adb12120e6cdcfacceff 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 struct Foo<A, B, C = (A, B)>;
 
 impl<A, B, C = (A, B)> Foo<A, B, C> {
index ceaed9438be53c09bc2ac15145b8045b7b641086..696235333a123004cbf946184d1ece2bda559a9c 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 struct Heap;
 
 struct Vec<T, A = Heap>;
index 0b6480fc17dcc79eceb27a4daa357b47ea28ab2a..0cfb05b9332a4ae5d5481d9baa7ae2183fc736cb 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 struct Heap;
 
 struct Vec<A = Heap, T>; //~ ERROR type parameters with a default must be trailing
index ec226061e2abed207765581e4c8edd18f63a40db..f25d8f99b8d5449d45dcfa1c5734662a212ed92c 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 struct Heap;
 
 struct Vec<T, A = Heap>;
index b16abd1757548e0a82c378c544d72ca6b258d306..ee3e1818779f355dae149578bc16f234c39bbd79 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 struct Heap;
 
 struct Vec<T, A = Heap>;
index ace53fb51a4056515222f395e204acf4e5954e4f..eda1b014fa7a4a54dc01eec1cdfea22c687f7174 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 // Ensure that we get an error and not an ICE for this problematic case.
 struct Foo<T = Option<U>, U = bool>;
 //~^ ERROR type parameters with a default cannot use forward declared identifiers
index 1c14644ec186dc50d104778c72d97dbbadaa250e..5bdee543d738de77c87f5226a46b09855f41e62d 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 struct A;
 struct B;
 struct C;
index 459a5d8c9e3cbbca112240d824baa5c8ee915b2d..d8258a72ce35ba801eb82dac21370484110081c5 100644 (file)
@@ -10,8 +10,6 @@
 
 // Make sure that globs only bring in public things.
 
-#![feature(globs)]
-
 use bar::*;
 
 mod bar {
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 210a47d2d039c0fc5f412f01f2e3877e6f6cce5a..21aa811ea718869f6350e1686e6565936f66c318 100644 (file)
@@ -10,8 +10,6 @@
 
 // error-pattern: unresolved name
 
-#![feature(globs)]
-
 use module_of_many_things::*;
 
 mod module_of_many_things {
index 39b18e1c445a222ed6450a68c08a34c6941f242b..fda7b190d72b4ff8b1c0eb91438917ff1800f6ff 100644 (file)
@@ -10,8 +10,6 @@
 
 // error-pattern: unresolved
 
-#![feature(globs)]
-
 mod circ1 {
     pub use circ2::f2;
     pub fn f1() { println!("f1"); }
index 007b28b6924e45cd893a53bdb63a99ecf439bb8a..eac5a98140f8903b11e146153794e9adff603cbc 100644 (file)
@@ -11,7 +11,6 @@
 // Test that import shadowing using globs causes errors
 
 #![no_implicit_prelude]
-#![feature(globs)]
 
 use foo::*;
 use bar::*; //~ERROR a type named `Baz` has already been imported in this module
index e597b557383866cc344b0cde275fc1bbd32475f2..8b0809fd55a8a0e3188805a51f2b69f270ed6652 100644 (file)
@@ -11,7 +11,6 @@
 // Test that import shadowing using globs causes errors
 
 #![no_implicit_prelude]
-#![feature(globs)]
 
 use foo::*;
 use foo::*; //~ERROR a type named `Baz` has already been imported in this module
index 68222fa3fd727e2a03d99107d3aa4a870982a8dd..cef481af6ba5f319310996e01056878c4753c5f2 100644 (file)
@@ -11,7 +11,6 @@
 // Test that import shadowing using globs causes errors
 
 #![no_implicit_prelude]
-#![feature(globs)]
 
 use foo::Baz;
 use bar::*; //~ERROR a type named `Baz` has already been imported in this module
index c698004bda0e48b2e73caf1cb1ec84c22190a2b6..919eea0e04601f9e3be3f6d9b5ff7227b21061a2 100644 (file)
@@ -11,7 +11,6 @@
 // Test that import shadowing using globs causes errors
 
 #![no_implicit_prelude]
-#![feature(globs)]
 
 use foo::*;
 use bar::Baz; //~ERROR a type named `Baz` has already been imported in this module
index 6ad7e5ec3e260b5cea826f30468d7199b4ff3137..df17b7f0a2057b69fe259b752c5dff3d68fe1ea6 100644 (file)
@@ -11,7 +11,6 @@
 // Test that import shadowing using globs causes errors
 
 #![no_implicit_prelude]
-#![feature(globs)]
 
 use foo::Baz;
 use bar::Baz; //~ERROR a type named `Baz` has already been imported in this module
index 1864251e71b4212dd58a6ce847a7a33747f45dc5..94269043b02052b75a5e9e3bfa3fab87edd35ac5 100644 (file)
@@ -11,7 +11,6 @@
 // Test that import shadowing using globs causes errors
 
 #![no_implicit_prelude]
-#![feature(globs)]
 
 use qux::*;
 use foo::*; //~ERROR a type named `Baz` has already been imported in this module
index a2df266fb74f3b912593cdc5fe3c2e467c54cb82..b3bac380710cda4ebed6656fd5490692cabbbc2f 100644 (file)
@@ -11,7 +11,6 @@
 // Test that import shadowing using globs causes errors
 
 #![no_implicit_prelude]
-#![feature(globs)]
 
 use foo::*;
 use qux::*; //~ERROR a type named `Baz` has already been imported in this module
index ab770c099e125a04e2798f241f4522f1d4d0b519..f0b9e796ae62dd62b3f2b7ce01c17b6fe7fc93f7 100644 (file)
@@ -10,8 +10,6 @@
 
 // error-pattern: reached the recursion limit while auto-dereferencing
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 struct Foo;
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 46d9a558d9ea973bf8b6e3c75a45e5680b334c1b..f2d858391cea2ae5b10f0d298ec7318e5ef92ba1 100644 (file)
@@ -10,8 +10,6 @@
 
 // Testing that we don't fail abnormally after hitting the errors
 
-#![feature(globs)]
-
 use unresolved::*; //~ ERROR unresolved import `unresolved::*`. Maybe a missing `extern crate unres
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-17904.rs b/src/test/compile-fail/issue-17904.rs
new file mode 100644 (file)
index 0000000..96ba712
--- /dev/null
@@ -0,0 +1,17 @@
+// 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.
+
+struct Baz<U> where U: Eq(U); //This is parsed as the new Fn* style parenthesis syntax.
+struct Baz<U> where U: Eq(U) -> R; // Notice this parses as well.
+struct Baz<U>(U) where U: Eq; // This rightfully signals no error as well.
+struct Foo<T> where T: Copy, (T); //~ ERROR unexpected token in `where` clause
+struct Bar<T> { x: T } where T: Copy //~ ERROR expected item, found `where`
+
+fn main() {}
index 38ebbc062f048f5d422d418bbdcc20acb699b436..37bb1cb1911e5a9fd3fab55154cf285a4d0cdfcd 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![feature(unboxed_closures)]
-#![feature(associated_types)]
 
 use std::any::Any;
 use std::intrinsics::TypeId;
index 491707a9e3104706411a5e21b13c28a05b62c9a2..0d1a1f16c2c932d34ea64707065193248aac1b05 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 struct MyPtr<'a>(&'a mut uint);
index 49eeccb2b0cf177177d45ed3339c040ba5bd4a9c..95782630efc82e622f19cc7c126f8581d7dfa7d9 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 fn add_state(op: <int as HasState>::State) {
 //~^ ERROR the trait `HasState` is not implemented for the type `int`
 }
index 32a51ee065b177daace40ac5b38a3985c46b04a2..3a9de74104364156b4279f01008e421ff32ae11f 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Foo {
     type Item;
 }
index 1a792eb6e76aedacc37ded3d389835d73f060221..7aba1bc8e65c7a4b30cb8718d27aa78ad450f2bd 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Foo for Sized? { fn foo<T>(&self, ext_thing: &T); }
-pub trait Bar for Sized?: Foo { }
+pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+pub trait Bar: Foo { }
 impl<T: Foo> Bar for T { }
 
 pub struct Thing;
index 196a04db18a3886de1b8793573380b960293c4ca..70fe6b9b6a868acac98a548e29fd31dcb6b60a48 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait From<Src> {
     type Output;
 
index d9520583ca53bc7e9ec8deb38f2576dbf8eb3546..b52f2b1b13857231b830f69492590d09114311eb 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait From<Src> {
     type Result;
 
index 373e7339b693988fd2f18a5e234384929036b654..289e9855525ac14873a090a2a25a7ac4b3333ecf 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
-
 // ensures that 'use foo:*' doesn't import non-public item
 
 use m1::*;
@@ -36,4 +34,3 @@ fn foo() {}
 fn main() {
     foo(); //~ ERROR: unresolved name
 }
-
index 7959078359cf0984a2bef0607cc1392db7037bc4..289aa21e1cba54000cc5ec17cc9606d1187a7b9d 100644 (file)
@@ -13,8 +13,6 @@
 // ensures that 'use foo:*' doesn't import non-public 'use' statements in the
 // module 'foo'
 
-#![feature(globs)]
-
 use m1::*;
 
 mod foo {
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 8d8e87da76e07672b63c4913c19645bf4e4e4c46..7e3f1171e252f5ba77908738ee02269cef1c017b 100644 (file)
@@ -8,10 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
-
 use self::*; //~ ERROR: unresolved import
 
 fn main() {
 }
-
index b73c3fa26105081355f4f5027eec7df989dbc76f..e50f636050c536b8fe5231f764187d42a781b2cc 100644 (file)
@@ -10,7 +10,6 @@
 
 // When denying at the crate level, be sure to not get random warnings from the
 // injected intrinsics by the compiler.
-#![feature(globs)]
 #![deny(missing_docs)]
 #![allow(dead_code)]
 #![allow(missing_copy_implementations)]
diff --git a/src/test/compile-fail/lint-raw-ptr-derive.rs b/src/test/compile-fail/lint-raw-ptr-derive.rs
new file mode 100644 (file)
index 0000000..3198e78
--- /dev/null
@@ -0,0 +1,34 @@
+// 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.
+
+#![allow(dead_code)]
+#![deny(raw_pointer_derive)]
+
+#[derive(Clone)]
+struct Foo {
+    x: *const int //~ ERROR use of `#[derive]` with a raw pointer
+}
+
+#[derive(Clone)]
+struct Bar(*mut int); //~ ERROR use of `#[derive]` with a raw pointer
+
+#[derive(Clone)]
+enum Baz {
+    A(*const int), //~ ERROR use of `#[derive]` with a raw pointer
+    B { x: *mut int } //~ ERROR use of `#[derive]` with a raw pointer
+}
+
+#[derive(Clone)]
+struct Buzz {
+    x: (*const int, //~ ERROR use of `#[derive]` with a raw pointer
+        *const uint) //~ ERROR use of `#[derive]` with a raw pointer
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/lint-raw-ptr-deriving.rs b/src/test/compile-fail/lint-raw-ptr-deriving.rs
deleted file mode 100644 (file)
index 6fe8862..0000000
+++ /dev/null
@@ -1,34 +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.
-
-#![allow(dead_code)]
-#![deny(raw_pointer_deriving)]
-
-#[derive(Clone)]
-struct Foo {
-    x: *const int //~ ERROR use of `#[derive]` with a raw pointer
-}
-
-#[derive(Clone)]
-struct Bar(*mut int); //~ ERROR use of `#[derive]` with a raw pointer
-
-#[derive(Clone)]
-enum Baz {
-    A(*const int), //~ ERROR use of `#[derive]` with a raw pointer
-    B { x: *mut int } //~ ERROR use of `#[derive]` with a raw pointer
-}
-
-#[derive(Clone)]
-struct Buzz {
-    x: (*const int, //~ ERROR use of `#[derive]` with a raw pointer
-        *const uint) //~ ERROR use of `#[derive]` with a raw pointer
-}
-
-fn main() {}
index 8e1723ddab24cc8848e76f84c57ca5a3e25599a8..0e24269ec444905b96e3e335efe2348b37822ce5 100644 (file)
 // aux-build:stability_cfg1.rs
 // aux-build:stability_cfg2.rs
 
-#![feature(globs, 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 93190a0ffe5cd0d7b3670c4167cc8974109ee844..a77de551f5d2cf6418c0b15ddc80d848bb680d5b 100644 (file)
@@ -10,7 +10,6 @@
 
 // aux-build:lint-unused-extern-crate.rs
 
-#![feature(globs)]
 #![deny(unused_extern_crates)]
 #![allow(unused_variables)]
 
index b1a6c82a734fe20003c2f342cc03dbd3dccf8eee..b5c0dce6e531ee8800b8cf37a60622d56cb16330 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
 #![deny(unused_imports)]
 #![allow(dead_code)]
 
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 fd5f5866f094085fe0cebc8d4691484ebbbd9d47..0e85551e2161caee9f4882ef0731057bcb95fc67 100644 (file)
@@ -10,7 +10,7 @@
 
 fn main() {
     assert!(1 == 2)
-    assert!(3 == 4) //~ ERROR expected one of `.`, `;`, or `}`, found `assert`
+    assert!(3 == 4) //~ ERROR expected one of `.`, `;`, `}`, or an operator, found `assert`
     println!("hello");
 }
 
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/mut-pattern-internal-mutability.rs b/src/test/compile-fail/mut-pattern-internal-mutability.rs
new file mode 100644 (file)
index 0000000..05c6c4a
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    let foo = &mut 1i;
+
+    let &mut x = foo;
+    x += 1; //~ ERROR re-assignment of immutable variable
+
+    // explicitly mut-ify internals
+    let &mut mut x = foo;
+    x += 1;
+
+    // check borrowing is detected successfully
+    let &mut ref x = foo;
+    *foo += 1; //~ ERROR cannot assign to `*foo` because it is borrowed
+}
diff --git a/src/test/compile-fail/mut-pattern-mismatched.rs b/src/test/compile-fail/mut-pattern-mismatched.rs
new file mode 100644 (file)
index 0000000..81985a3
--- /dev/null
@@ -0,0 +1,26 @@
+// 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() {
+    let foo = &mut 1i;
+
+    // (separate lines to ensure the spans are accurate)
+
+    // SNAP b2085d9 uncomment this after the next snapshot
+    // NOTE(stage0) just in case tidy doesn't check snap's in tests
+    // let &_ // ~ ERROR expected `&mut int`, found `&_`
+    //    = foo;
+    let &mut _ = foo;
+
+    let bar = &1i;
+    let &_ = bar;
+    let &mut _ //~ ERROR expected `&int`, found `&mut _`
+         = bar;
+}
index b5c0157cb5e29ed3604b141f14fb827561e504e1..2f0588b261e54c08eaded6acb19e6f527b442d83 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
-
 // error-pattern:declaration of `None` shadows
 use std::option::*;
 
index 120f092d732f92199f1ee61320a077218d4db8ea..4fcb31d36865aa55793ad1d2bdf537a2fff63111 100644 (file)
@@ -9,8 +9,6 @@
 // except according to those terms.
 
 // aux-build:namespaced_enums.rs
-#![feature(globs)]
-
 extern crate namespaced_enums;
 
 mod m {
@@ -25,4 +23,3 @@ pub fn main() {
     bar(); //~ ERROR unresolved name `bar`
     m::bar(); //~ ERROR unresolved name `m::bar`
 }
-
index a8f4e6ba0903b6ac9e599b4fd02f43eb0442d5cd..602ec9ba762802aff39a439c2845bce82171d603 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.
-#![feature(globs)]
 
 mod m2 {
     pub enum Foo {
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`
+    }
+}
diff --git a/src/test/compile-fail/obsolete-for-sized.rs b/src/test/compile-fail/obsolete-for-sized.rs
new file mode 100644 (file)
index 0000000..1b86d08
--- /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.
+
+// Test that we generate obsolete syntax errors around usages of `for Sized?`
+
+trait Foo for Sized? {} //~ ERROR obsolete syntax: for Sized?
+
+trait Bar for ?Sized {} //~ ERROR obsolete syntax: for Sized?
+
+fn main() { }
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 2862268b552579f9c1545247177ff89af29831c9..5952f05b7bc4c7b36426147ec6f8db3f7b695953 100644 (file)
@@ -11,7 +11,6 @@
 // Check we do the correct privacy checks when we import a name and there is an
 // item with that name in both the value and type namespaces.
 
-#![feature(globs)]
 #![allow(dead_code)]
 #![allow(unused_imports)]
 
@@ -64,4 +63,3 @@ fn test_glob3() {
 
 fn main() {
 }
-
index 769bdae80f118d74226f5439b5d662379d49a8ed..7fe0574ab7d9a663902dd9433fcc6a01145f3b4c 100644 (file)
@@ -11,7 +11,6 @@
 // Check we do the correct privacy checks when we import a name and there is an
 // item with that name in both the value and type namespaces.
 
-#![feature(globs)]
 #![allow(dead_code)]
 #![allow(unused_imports)]
 
@@ -88,4 +87,3 @@ fn test_list3() {
 
 fn main() {
 }
-
index 41621a934d17abd4dbcab663b46f34cf77a0b0a9..ffee00642acf6f800b01ce594e68182e1058f379 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs, lang_items)]
+#![feature(lang_items)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
 #[lang="sized"]
index 1a94751b46bfe9d01ab2c672b51ec9e52cf95f98..b38d7aedf841ccb5f3b3bdbd8405dfbbf00cbd82 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
 // Test to make sure that globs don't leak in regular `use` statements.
@@ -34,4 +33,3 @@ fn test2() {
 }
 
 #[start] fn main(_: int, _: *const *const u8) -> int { 3 }
-
index 4c67a9910cfe9ebf2dd83ec15f97e90e88b8fd9a..5ec10d5a4caa94458364e3c251d3d99817240231 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
 // Test to make sure that private items imported through globs remain private
index 70e7e2df98a690d4f9e29628fa400d775b2dd674..92f3a57c69d0b784f17d8f6f354502b7238f0ca2 100644 (file)
@@ -8,10 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs, lang_items)]
+#![feature(lang_items)]
 #![no_std] // makes debugging this test *a lot* easier (during resolve)
 
-#[lang = "sized"] pub trait Sized for Sized? {}
+#[lang = "sized"] pub trait Sized {}
 #[lang="copy"] pub trait Copy {}
 
 // Test to make sure that private items imported through globs remain private
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"]
 
diff --git a/src/test/compile-fail/regions-close-associated-type-into-object.rs b/src/test/compile-fail/regions-close-associated-type-into-object.rs
new file mode 100644 (file)
index 0000000..8163145
--- /dev/null
@@ -0,0 +1,81 @@
+// 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.
+
+trait X {}
+
+trait Iter {
+    type Item: X;
+
+    fn into_item(self) -> Self::Item;
+    fn as_item(&self) -> &Self::Item;
+}
+
+fn bad1<T: Iter>(v: T) -> Box<X+'static>
+{
+    let item = v.into_item();
+    box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+}
+
+fn bad2<T: Iter>(v: T) -> Box<X+'static>
+    where Box<T::Item> : X
+{
+    let item = box v.into_item();
+    box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+}
+
+fn bad3<'a, T: Iter>(v: T) -> Box<X+'a>
+{
+    let item = v.into_item();
+    box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+}
+
+fn bad4<'a, T: Iter>(v: T) -> Box<X+'a>
+    where Box<T::Item> : X
+{
+    let item = box v.into_item();
+    box item //~ ERROR associated type `<T as Iter>::Item` may not live long enough
+}
+
+fn ok1<'a, T: Iter>(v: T) -> Box<X+'a>
+    where T::Item : 'a
+{
+    let item = v.into_item();
+    box item // OK, T::Item : 'a is declared
+}
+
+fn ok2<'a, T: Iter>(v: &T, w: &'a T::Item) -> Box<X+'a>
+    where T::Item : Clone
+{
+    let item = Clone::clone(w);
+    box item // OK, T::Item : 'a is implied
+}
+
+fn ok3<'a, T: Iter>(v: &'a T) -> Box<X+'a>
+    where T::Item : Clone + 'a
+{
+    let item = Clone::clone(v.as_item());
+    box item // OK, T::Item : 'a was declared
+}
+
+fn meh1<'a, T: Iter>(v: &'a T) -> Box<X+'a>
+    where T::Item : Clone
+{
+    // This case is kind of interesting. It's the same as `ok3` but
+    // without the explicit declaration. In principle, it seems like
+    // we ought to be able to infer that `T::Item : 'a` because we
+    // invoked `v.as_self()` which yielded a value of type `&'a
+    // T::Item`. But we're not that smart at present.
+
+    let item = Clone::clone(v.as_item());
+    box item //~ ERROR associated type `<T as Iter>::Item` may not live
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/regions-close-param-into-object.rs b/src/test/compile-fail/regions-close-param-into-object.rs
new file mode 100644 (file)
index 0000000..3e91d09
--- /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.
+
+
+trait X {}
+
+fn p1<T>(v: T) -> Box<X+'static>
+    where T : X
+{
+    box v //~ ERROR parameter type `T` may not live long enough
+}
+
+fn p2<T>(v: Box<T>) -> Box<X+'static>
+    where Box<T> : X
+{
+    box v //~ ERROR parameter type `T` may not live long enough
+}
+
+fn p3<'a,T>(v: T) -> Box<X+'a>
+    where T : X
+{
+    box v //~ ERROR parameter type `T` may not live long enough
+}
+
+fn p4<'a,T>(v: Box<T>) -> Box<X+'a>
+    where Box<T> : X
+{
+    box v //~ ERROR parameter type `T` may not live long enough
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/regions-pattern-typing-issue-19552.rs b/src/test/compile-fail/regions-pattern-typing-issue-19552.rs
new file mode 100644 (file)
index 0000000..3f722c9
--- /dev/null
@@ -0,0 +1,18 @@
+// 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 assert_send<T: Send>(_t: T) {}
+
+fn main() {
+    let line = String::new();
+    match [line.as_slice()] { //~ ERROR `line` does not live long enough
+        [ word ] => { assert_send(word); }
+    }
+}
diff --git a/src/test/compile-fail/regions-pattern-typing-issue-19997.rs b/src/test/compile-fail/regions-pattern-typing-issue-19997.rs
new file mode 100644 (file)
index 0000000..da839d7
--- /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.
+
+fn main() {
+    let a0 = 0u8;
+    let f = 1u8;
+    let mut a1 = &a0;
+    match (&a1,) {
+        (&ref b0,) => {
+            a1 = &f; //~ ERROR cannot assign
+        }
+    }
+}
index dd11ec645b42ebfc48ed9c7dfdf83f11c92bd480..ae561878e9ba0dcbfa9f352bb8035c32ec81dc2a 100644 (file)
@@ -11,7 +11,7 @@
 #![feature(lang_items)]
 #![no_std]
 
-#[lang="sized"] pub trait Sized for Sized? {}
+#[lang="sized"] pub trait Sized {}
 
 // error-pattern:requires `start` lang_item
 
index 2bdbdb4fde29596fe38d7dc9b86d80128d85e23f..d58e89e7767e813e0c380b0a34bf3d1c96355399 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 struct StateMachineIter<'a> {
     statefn: &'a StateMachineFunc<'a>
 }
@@ -61,4 +59,3 @@ fn main() {
     println!("{}",it.next());
     println!("{}",it.next());
 }
-
index a97a3e61678191f4e0367472cb901c2e016678e5..5ebabc2e3548c1032eb007b08db97dc2e9b09d48 100644 (file)
@@ -10,7 +10,6 @@
 
 // Issue #8380
 
-#![feature(globs)]
 
 use std::sync::atomic::*;
 use std::ptr;
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 5e81a4cec2284b915ad942b53294dfbc8ca9b0d2..31456853e1c0f1543207f7c0776e36861700fe91 100644 (file)
 
 use std::mem::transmute;
 
-fn a<T, Sized? U>(x: &[T]) -> &U {
+fn a<T, U: ?Sized>(x: &[T]) -> &U {
     unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
 }
 
-fn b<Sized? T, Sized? U>(x: &T) -> &U {
+fn b<T: ?Sized, U: ?Sized>(x: &T) -> &U {
     unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
 }
 
@@ -30,11 +30,11 @@ fn d<T, U>(x: &[T]) -> &[U] {
     unsafe { transmute(x) }
 }
 
-fn e<Sized? T, U>(x: &T) -> &U {
+fn e<T: ?Sized, U>(x: &T) -> &U {
     unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
 }
 
-fn f<T, Sized? U>(x: &T) -> &U {
+fn f<T, U: ?Sized>(x: &T) -> &U {
     unsafe { transmute(x) } //~ ERROR transmute called on types with potentially different sizes
 }
 
index 8b5a8c679b245b6392883f23c1cda222c5038fa5..a68bba285df29b39741ca7db9a78a5c4771715e4 100644 (file)
 
 use std::mem::transmute;
 
-struct Foo<Sized? T> {
+struct Foo<T: ?Sized> {
     t: Box<T>
 }
 
-impl<Sized? T> Foo<T> {
+impl<T: ?Sized> Foo<T> {
     fn m(x: &T) -> &int where T : Sized {
         // OK here, because T : Sized is in scope.
         unsafe { transmute(x) }
index 06a934063927a8b06620e294d7f1fad034088d0a..82355ddf68176e751436e36385dab837c3c1adfb 100644 (file)
 // Test interaction between unboxed closure sugar and default type
 // parameters (should be exactly as if angle brackets were used).
 
-#![feature(default_type_params, unboxed_closures)]
+#![feature(unboxed_closures)]
 #![allow(dead_code)]
 
 trait Foo<T,U,V=T> {
     fn dummy(&self, t: T, u: U, v: V);
 }
 
-trait Eq<Sized? X> for Sized? { }
-impl<Sized? X> Eq<X> for X { }
-fn eq<Sized? A,Sized? B>() where A : Eq<B> { }
+trait Eq<X: ?Sized> { }
+impl<X: ?Sized> Eq<X> for X { }
+fn eq<A: ?Sized,B: ?Sized>() where A : Eq<B> { }
 
 fn test<'a,'b>() {
     // Parens are equivalent to omitting default in angle.
index 16d6b217872ae8b2403396115e7394a4ba0d2932..f36fad306704ff14dc732badf019a0824cc4b559 100644 (file)
@@ -20,9 +20,9 @@ trait Foo<T,U> {
     fn dummy(&self, t: T, u: U);
 }
 
-trait Eq<Sized? X> for Sized? { }
-impl<Sized? X> Eq<X> for X { }
-fn eq<Sized? A,Sized? B:Eq<A>>() { }
+trait Eq<X: ?Sized> { }
+impl<X: ?Sized> Eq<X> for X { }
+fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
 fn test<'a,'b>() {
     // No errors expected:
index e08d84944c02a58beaa20727a81154ccb9897fe6..2617be295cd2a0542f8528ff2842d276da0e754d 100644 (file)
@@ -20,9 +20,9 @@ trait Foo<T,U> {
     fn dummy(&self, t: T, u: U);
 }
 
-trait Eq<Sized? X> for Sized? { }
-impl<Sized? X> Eq<X> for X { }
-fn eq<Sized? A,Sized? B:Eq<A>>() { }
+trait Eq<X: ?Sized> { }
+impl<X: ?Sized> Eq<X> for X { }
+fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
 fn main() {
     eq::< for<'a> Foo<(&'a int,), &'a int>,
index a938f126c16077f6925c4a65a7fda0825d8029ed..5ace9e115ec78bc79b1adafe3b6615e1135ae94b 100644 (file)
@@ -12,7 +12,7 @@
 // parameters (should be exactly as if angle brackets were used
 // and regions omitted).
 
-#![feature(default_type_params, unboxed_closures)]
+#![feature(unboxed_closures)]
 #![allow(dead_code)]
 
 use std::kinds::marker;
@@ -21,9 +21,9 @@ trait Foo<'a,T,U> {
     fn dummy(&'a self) -> &'a (T,U);
 }
 
-trait Eq<Sized? X> for Sized? { }
-impl<Sized? X> Eq<X> for X { }
-fn eq<Sized? A,Sized? B:Eq<A>>() { }
+trait Eq<X: ?Sized> { }
+impl<X: ?Sized> Eq<X> for X { }
+fn eq<A: ?Sized,B: ?Sized +Eq<A>>() { }
 
 fn same_type<A,B:Eq<A>>(a: A, b: B) { }
 
index 7b5d42954117cb313ba9f28cb26791f616c48405..2de490e018b44de240f5a898585840aac5946ce5 100644 (file)
@@ -9,5 +9,5 @@
 // except according to those terms.
 
 fn bar<T: Sized>() { }
-fn foo<Sized? T>() { bar::<T>() } //~ ERROR the trait `core::kinds::Sized` is not implemented
+fn foo<T: ?Sized>() { bar::<T>() } //~ ERROR the trait `core::kinds::Sized` is not implemented
 fn main() { }
index 0462a2025d2ce72dac239bede11451bbe31b6242..aea236c9268157928593407a3e2bc85a4ccd4bbe 100644 (file)
 
 
 fn is_sized<T:Sized>() { }
-fn not_sized<Sized? T>() { }
+fn not_sized<T: ?Sized>() { }
 
 enum Foo<U> { FooSome(U), FooNone }
 fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
-fn foo2<Sized? T>() { not_sized::<Foo<T>>() }
+fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
 //~^ ERROR the trait `core::kinds::Sized` is not implemented
 //
 // Not OK: `T` is not sized.
 
-enum Bar<Sized? U> { BarSome(U), BarNone }
-fn bar1<Sized? T>() { not_sized::<Bar<T>>() }
-fn bar2<Sized? T>() { is_sized::<Bar<T>>() }
+enum Bar<U: ?Sized> { BarSome(U), BarNone }
+fn bar1<T: ?Sized>() { not_sized::<Bar<T>>() }
+fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
 //~^ ERROR the trait `core::kinds::Sized` is not implemented
 //
 // Not OK: `Bar<T>` is not sized, but it should be.
index 2c8a2b361d596be0a6e15ade8dff5ea4d9f19143..8740346a21750c8918af9545e4ceda6d20a0286b 100644 (file)
@@ -14,7 +14,7 @@
 
 struct S5<Y>;
 
-impl<Sized? X> S5<X> { //~ ERROR not implemented
+impl<X: ?Sized> S5<X> { //~ ERROR not implemented
 }
 
 fn main() { }
index db2e9cb932800d5d4aa7c1f2482e6303874dad98..89c711036977a68addd796bfedd63652ad312293 100644 (file)
 
 
 fn is_sized<T:Sized>() { }
-fn not_sized<Sized? T>() { }
+fn not_sized<T: ?Sized>() { }
 
 struct Foo<T> { data: T }
 fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
-fn foo2<Sized? T>() { not_sized::<Foo<T>>() }
+fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
 //~^ ERROR the trait `core::kinds::Sized` is not implemented
 //
 // Not OK: `T` is not sized.
 
-struct Bar<Sized? T> { data: T }
-fn bar1<Sized? T>() { not_sized::<Bar<T>>() }
-fn bar2<Sized? T>() { is_sized::<Bar<T>>() }
+struct Bar<T: ?Sized> { data: T }
+fn bar1<T: ?Sized>() { not_sized::<Bar<T>>() }
+fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
 //~^ ERROR the trait `core::kinds::Sized` is not implemented
 //
 // Not OK: `Bar<T>` is not sized, but it should be.
index 0f0a97fab4d7580560e214803861d4d8b99f3953..3dd55b0ba7d23401d7c75e5922efd5c2f23038b5 100644 (file)
 // Test sized-ness checking in substitution in impls.
 
 // impl - struct
-trait T3<Sized? Z> {
+trait T3<Z: ?Sized> {
 }
 
 struct S5<Y>;
 
-impl<Sized? X> T3<X> for S5<X> { //~ ERROR not implemented
+impl<X: ?Sized> T3<X> for S5<X> { //~ ERROR not implemented
 }
 
 fn main() { }
index bdb652b168a8c5fac1bd12379f53bb7d416b3c3c..7ae74fc2600c84d71416e431f997c6840278b901 100644 (file)
@@ -13,8 +13,8 @@
 // impl - unbounded
 trait T2<Z> {
 }
-struct S4<Sized? Y>;
-impl<Sized? X> T2<X> for S4<X> {
+struct S4<Y: ?Sized>;
+impl<X: ?Sized> T2<X> for S4<X> {
     //~^ ERROR `core::kinds::Sized` is not implemented for the type `X`
 }
 
index 43db4dfd395b059e1cbd835d653a1f28b28928ab..92dbea0424b6f6627bcd1faccf790bd64faae656 100644 (file)
@@ -10,7 +10,7 @@
 
 // Test syntax checks for `type` keyword.
 
-struct S1 for type; //~ ERROR expected `{`, `(`, or `;` after struct name, found `for`
+struct S1 for type; //~ ERROR expected `where`, `{`, `(`, or `;` after struct name, found `for`
 
 pub fn main() {
 }
index 0a75240f2d89df613224e0d8fd16e8299df98441..9b7d10b0d0f761a3c4f6edf45bb8c0361aa4b06b 100644 (file)
@@ -12,7 +12,7 @@
 
 
 // Unbounded.
-fn f1<Sized? X>(x: &X) {
+fn f1<X: ?Sized>(x: &X) {
     f2::<X>(x);
     //~^ ERROR the trait `core::kinds::Sized` is not implemented
 }
@@ -20,8 +20,8 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T for Sized? {}
-fn f3<Sized? X: T>(x: &X) {
+trait T {}
+fn f3<X: ?Sized + T>(x: &X) {
     f4::<X>(x);
     //~^ ERROR the trait `core::kinds::Sized` is not implemented
 }
@@ -29,13 +29,13 @@ fn f4<X: T>(x: &X) {
 }
 
 // Test with unsized enum.
-enum E<Sized? X> {
+enum E<X: ?Sized> {
     V(X),
 }
 
 fn f5<Y>(x: &Y) {}
-fn f6<Sized? X>(x: &X) {}
-fn f7<Sized? X>(x1: &E<X>, x2: &E<X>) {
+fn f6<X: ?Sized>(x: &X) {}
+fn f7<X: ?Sized>(x1: &E<X>, x2: &E<X>) {
     f5(x1);
     //~^ ERROR the trait `core::kinds::Sized` is not implemented
     f6(x2); // ok
@@ -43,23 +43,23 @@ fn f7<Sized? X>(x1: &E<X>, x2: &E<X>) {
 
 
 // Test with unsized struct.
-struct S<Sized? X> {
+struct S<X: ?Sized> {
     x: X,
 }
 
-fn f8<Sized? X>(x1: &S<X>, x2: &S<X>) {
+fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
     f5(x1);
     //~^ ERROR the trait `core::kinds::Sized` is not implemented
     f6(x2); // ok
 }
 
 // Test some tuples.
-fn f9<Sized? X>(x1: Box<S<X>>, x2: Box<E<X>>) {
+fn f9<X: ?Sized>(x1: Box<S<X>>, x2: Box<E<X>>) {
     f5(&(*x1, 34i));
     //~^ ERROR the trait `core::kinds::Sized` is not implemented
 }
 
-fn f10<Sized? X>(x1: Box<S<X>>, x2: Box<E<X>>) {
+fn f10<X: ?Sized>(x1: Box<S<X>>, x2: Box<E<X>>) {
     f5(&(32i, *x2));
     //~^ ERROR the trait `core::kinds::Sized` is not implemented
 }
index f9ece8e6843db8756d0c6cbd4a80d4d28d229577..f8b8ad2bf2efa4ee0b749ec7393599ba57e032c7 100644 (file)
@@ -11,7 +11,7 @@
 // Test that bounds are sized-compatible.
 
 trait T : Sized {}
-fn f<Sized? Y: T>() {
+fn f<Y: ?Sized + T>() {
 //~^ERROR incompatible bounds on `Y`, bound `T` does not allow unsized type
 }
 
index d9d7a86889f5771f741b6a76cf458000ae01bd42..f7477d746fae42faac883697deb0af0e5b681b28 100644 (file)
 
 // Test `Sized?` types not allowed in fields (except the last one).
 
-struct S1<Sized? X> {
+struct S1<X: ?Sized> {
     f1: X, //~ ERROR `core::kinds::Sized` is not implemented
     f2: int,
 }
-struct S2<Sized? X> {
+struct S2<X: ?Sized> {
     f: int,
     g: X, //~ ERROR `core::kinds::Sized` is not implemented
     h: int,
@@ -27,10 +27,10 @@ struct S4 {
     f: str, //~ ERROR `core::kinds::Sized` is not implemented
     g: uint
 }
-enum E<Sized? X> {
+enum E<X: ?Sized> {
     V1(X, int), //~ERROR `core::kinds::Sized` is not implemented
 }
-enum F<Sized? X> {
+enum F<X: ?Sized> {
     V2{f1: X, f: int}, //~ERROR `core::kinds::Sized` is not implemented
 }
 
index 0efd178f75b8c479a831a9f6e8456d773ac26c5a..b4f0a4912cf3019152bb6b9d1c1f359a9dc803aa 100644 (file)
 // Test `Sized?` local variables.
 
 
-trait T for Sized? {}
+trait T {}
 
-fn f1<Sized? X>(x: &X) {
+fn f1<X: ?Sized>(x: &X) {
     let _: X; // <-- this is OK, no bindings created, no initializer.
     let _: (int, (X, int)); // same
     let y: X; //~ERROR the trait `core::kinds::Sized` is not implemented
     let y: (int, (X, int)); //~ERROR the trait `core::kinds::Sized` is not implemented
 }
-fn f2<Sized? X: T>(x: &X) {
+fn f2<X: ?Sized + T>(x: &X) {
     let y: X; //~ERROR the trait `core::kinds::Sized` is not implemented
     let y: (int, (X, int)); //~ERROR the trait `core::kinds::Sized` is not implemented
 }
 
-fn f3<Sized? X>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f3<X: ?Sized>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
     let y: X = *x1; //~ERROR the trait `core::kinds::Sized` is not implemented
     let y = *x2; //~ERROR the trait `core::kinds::Sized` is not implemented
     let (y, z) = (*x3, 4i); //~ERROR the trait `core::kinds::Sized` is not implemented
 }
-fn f4<Sized? X: T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
+fn f4<X: ?Sized + T>(x1: Box<X>, x2: Box<X>, x3: Box<X>) {
     let y: X = *x1;         //~ERROR the trait `core::kinds::Sized` is not implemented
     let y = *x2;            //~ERROR the trait `core::kinds::Sized` is not implemented
     let (y, z) = (*x3, 4i); //~ERROR the trait `core::kinds::Sized` is not implemented
 }
 
-fn g1<Sized? X>(x: X) {} //~ERROR the trait `core::kinds::Sized` is not implemented
-fn g2<Sized? X: T>(x: X) {} //~ERROR the trait `core::kinds::Sized` is not implemented
+fn g1<X: ?Sized>(x: X) {} //~ERROR the trait `core::kinds::Sized` is not implemented
+fn g2<X: ?Sized + T>(x: X) {} //~ERROR the trait `core::kinds::Sized` is not implemented
 
 pub fn main() {
 }
index c0e6ae1db92c4aacc0a8b914eb81a81fe14b8c38..8a54771112f8e4189c77abee87a57b0428ac23d7 100644 (file)
 
 // Test sized-ness checking in substitution in impls.
 
-trait T for Sized? {}
+trait T {}
 
 // I would like these to fail eventually.
 // impl - bounded
 trait T1<Z: T> {
 }
-struct S3<Sized? Y>;
-impl<Sized? X: T> T1<X> for S3<X> {
+struct S3<Y: ?Sized>;
+impl<X: ?Sized + T> T1<X> for S3<X> {
     //~^ ERROR `core::kinds::Sized` is not implemented for the type `X`
 }
 
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 7aa6ead89d7e072c87de0ba9b2c7d9fd47dd1c48..e6fbcf2d38f2b2b317d5e6ce35e860a124c02984 100644 (file)
@@ -13,8 +13,6 @@
 // (In this case the mul method should take &f64 and not f64)
 // See: #11450
 
-#![feature(associated_types, default_type_params)]
-
 use std::ops::Mul;
 
 struct Vec1 {
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 939845a7b349a0d9353a0d6b3fae82f9bd54d251..6712b3b0659088e731147e0e4fd54bcc4287d6d3 100644 (file)
@@ -15,7 +15,6 @@
 // Expanded pretty printing causes resolve conflicts.
 
 // error-pattern:panic works
-#![feature(globs)]
 
 use std::*;
 
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 6e2ae117ce7ae97d44728a4c6aa60a9cf0c49213..8b8b7f169c5a0274f85fcfadea6add6dc98bb225 100644 (file)
@@ -20,7 +20,7 @@ fn drop(&mut self) {
 trait Trait {}
 impl Trait for Foo {}
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     f: T
 }
 
index deaf49228bc842810c92f671134d5dcb7843f530..743293c23f6adbb0c1e6ad8c55f19015fb4e99e9 100644 (file)
@@ -17,7 +17,7 @@ fn drop(&mut self) {
     }
 }
 
-struct Fat<Sized? T> {
+struct Fat<T: ?Sized> {
     f: T
 }
 
index fcfcce3ff1b78d879d9925ccf327e26907b7fc6c..3314b613201595442e4373c320795b189bc380ad 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Foo {
     type T;
 }
@@ -23,4 +21,3 @@ fn main() {
     let y: int = 44;
     assert_eq!(x * 2, y);
 }
-
index e3bd587742c3102ad89dd73169d2fb8928576485..caf7d31a5fd45c2f8fbf8b051265da9d3da07563 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test equality constraints on associated types in a where clause.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
index db5119132cc3fe1574edbf82b44a0cdc3124c22c..c34a19e1d8242206ad82a45c896fc67f933e7609 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test equality constraints on associated types in a where clause.
 
-#![feature(associated_types)]
-
 pub trait ToInt {
     fn to_int(&self) -> int;
 }
index c0cf917aa41174dc8a07f44ea1013263c9a4f636..58aa351ba9c41c27d45c2cad8596fdea9b52988d 100644 (file)
@@ -13,8 +13,6 @@
 // Test that we are able to reference cross-crate traits that employ
 // associated types.
 
-#![feature(associated_types)]
-
 extern crate "associated-types-cc-lib" as bar;
 
 use bar::Bar;
index 3b53203d218e047bb746e24d8764fd89c0a98e3d..6d59161ff93456fdaf1163bc02cc17033d8b30e2 100644 (file)
 // `Target=[A]`, then the impl marked with `(*)` is seen to conflict
 // with all the others.
 
-#![feature(associated_types, default_type_params)]
-
 use std::ops::Deref;
 
-pub trait MyEq<Sized? U=Self> for Sized? {
+pub trait MyEq<U: ?Sized=Self> {
     fn eq(&self, u: &U) -> bool;
 }
 
index ea2cf84b757c3b84a867bfcba7476e72a31b02ca..68b49af0d3b696539321500bea230ad9d8e3457e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait SignedUnsigned {
     type Opposite;
     fn convert(self) -> Self::Opposite;
@@ -39,4 +37,3 @@ fn main() {
     let x = get(22);
     assert_eq!(22u, x);
 }
-
index f0343a743cb5025b1fb926e12f1619ff4cd891ee..0ec8a3661906f7aaee7806a151ba4718339eb7da 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test equality constraints on associated types inside of an object type
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
index eb6a3111cc15ba3ad5ce397610c1b35d6735d86a..388a2d734473153f9b4c602bd59d99efa6cc51df 100644 (file)
@@ -16,7 +16,7 @@
 
 // ignore-pretty -- FIXME(#17362)
 
-#![feature(associated_types, lang_items, unboxed_closures)]
+#![feature(lang_items, unboxed_closures)]
 #![no_implicit_prelude]
 
 use std::kinds::Sized;
index e01b18a64db22098790ed22f24eb4ebe521898c3..0ae61037154728837200000a2174cbc53e907154 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
@@ -35,5 +33,3 @@ fn main() {
     };
     assert_eq!(*s.grab(), 100);
 }
-
-
index 4ed213e85d8787fd484776fd3aa0d8f36cda62ea..4104f520a0c5d714827f33f6cd384c9aedfafa3e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
@@ -36,4 +34,3 @@ fn main() {
     };
     assert_eq!(*grab(&s), 100);
 }
-
index f6aaaf3b3fa15d41512489924fb0bf14ebb25ca0..59f05e1184285c531c284be909093d127822a38b 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
@@ -44,4 +42,3 @@ fn main() {
     };
     assert_eq!(*s.grab(), 100);
 }
-
index 341682692460ff05cdccfa91e08f3bd4416473b9..951497709fd69955e6c7408b4f2f38e27bf12a51 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
@@ -38,4 +36,3 @@ fn main() {
     };
     assert_eq!(*Struct::grab(&s), 100);
 }
-
index a6fb2b9e2ea5390ba1f70d79b19788bbf02e9609..d35b7331d4dbfa757b68f2d072decf3dc1e0991f 100644 (file)
@@ -11,7 +11,6 @@
 // Test that we are able to have an impl that defines an associated type
 // before the actual trait.
 
-#![feature(associated_types)]
 impl X for f64 { type Y = int; }
 trait X {type Y; }
 fn main() {}
index 0fd477204215e10a6147a7e71372aabfb7c2e1b7..1d264655bc479b03d0b70308627e54275c7e389c 100644 (file)
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-#![feature(associated_types)]
-
 struct Splits<'a, T, P>;
 struct SplitsN<I>;
 
-trait SliceExt2 for Sized? {
+trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
index f09c27029d7fa448e90bf77eeb89c87ce2d439c2..742bab0578e9c2a9e3d25b47480583a4ed961327 100644 (file)
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
 
-#![feature(associated_types)]
-
 struct Splits<'a, T, P>;
 struct SplitsN<I>;
 
-trait SliceExt2 for Sized? {
+trait SliceExt2 {
     type Item;
 
     fn split2<'a, P>(&'a self, pred: P) -> Splits<'a, Self::Item, P>
index 92daee5225d01729edcd8fc88f28e658fa65f47c..24dae20b3e77e976a4b3d67b25e7753802afc901 100644 (file)
@@ -13,8 +13,6 @@
 // this case, the `Result=Self` binding in the supertrait listing of
 // `Int` was being ignored.
 
-#![feature(associated_types)]
-
 trait Not {
     type Result;
 
index 1b4eb2604a82bf4251ccfc5213b6af0c4ef04266..abbde16faefca14ffa4d81a441ad1cf9ba037c82 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Foo<T> {
     type Bar;
     fn get_bar() -> <Self as Foo<T>>::Bar;
index 1be09e1e0680d114330eff766b4ce4af3c616a14..e7a8061a3467aa4f6d8479fa2788829fccce42d4 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get<T> {
     fn get(&self) -> T;
 }
index 1c2ff4668954620254496632c69f5399cf775d21..b9b6d14f8a071decd2a4edef6644d4cfbcb4622e 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test equality constraints on associated types in a where clause.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
     fn boo(&self) -> <Self as Foo>::A;
index 82ae0d89b46057930c9137fa10227cdc56158489..9e388dc3d347e7932e2cb7fcdd589dba8c0760a7 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Get {
     type Value;
     fn get(&self) -> &<Self as Get>::Value;
@@ -32,4 +30,3 @@ fn main() {
     };
     assert_eq!(*s.get(), 100);
 }
-
index 28c06f51cebc25d2ba7075a8d5448f9dd896325e..880554b61b2ffa7fb751691b182bd16589dffcf7 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test paths to associated types using the type-parameter-only sugar.
 
-#![feature(associated_types)]
-
 pub trait Foo {
     type A;
     fn boo(&self) -> Self::A;
index 8a1a090e919cc407eab577591cf041cf8357148d..abbe250b6279a17051edf12a87281d7a6d367eb0 100644 (file)
@@ -16,7 +16,7 @@
 
 // ignore-pretty -- FIXME(#17362) pretty prints with `<<` which lexes wrong
 
-#![feature(associated_types, lang_items, unboxed_closures)]
+#![feature(lang_items, unboxed_closures)]
 #![no_implicit_prelude]
 
 use std::kinds::Sized;
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 c95cf0bfdee453d8c5a43bd9c20ecab323c39fb6..22c322b86c97963d800c3485a482d2c7aa2d846d 100644 (file)
@@ -12,7 +12,7 @@
 
 extern crate libc;
 
-use std::c_str::ToCStr;
+use std::ffi::CString;
 
 mod mlibc {
     use libc::{c_char, c_long, c_longlong};
@@ -24,11 +24,13 @@ mod mlibc {
 }
 
 fn atol(s: String) -> int {
-    s.as_slice().with_c_str(|x| unsafe { mlibc::atol(x) as int })
+    let c = CString::from_slice(s.as_bytes());
+    unsafe { mlibc::atol(c.as_ptr()) as int }
 }
 
 fn atoll(s: String) -> i64 {
-    s.as_slice().with_c_str(|x| unsafe { mlibc::atoll(x) as i64 })
+    let c = CString::from_slice(s.as_bytes());
+    unsafe { mlibc::atoll(c.as_ptr()) as i64 }
 }
 
 pub fn main() {
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() {
 
diff --git a/src/test/run-pass/coherence-bigint-int.rs b/src/test/run-pass/coherence-bigint-int.rs
deleted file mode 100644 (file)
index 1e90453..0000000
+++ /dev/null
@@ -1,20 +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.
-
-// aux-build:coherence-lib.rs
-
-extern crate "coherence-lib" as lib;
-use lib::Remote1;
-
-pub struct BigInt;
-
-impl Remote1<BigInt> for int { }
-
-fn main() { }
diff --git a/src/test/run-pass/coherence-bigint-vecint.rs b/src/test/run-pass/coherence-bigint-vecint.rs
deleted file mode 100644 (file)
index b100455..0000000
+++ /dev/null
@@ -1,20 +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.
-
-// aux-build:coherence-lib.rs
-
-extern crate "coherence-lib" as lib;
-use lib::Remote1;
-
-pub struct BigInt;
-
-impl Remote1<BigInt> for Vec<int> { }
-
-fn main() { }
diff --git a/src/test/run-pass/coherence-iterator-vec-any-elem.rs b/src/test/run-pass/coherence-iterator-vec-any-elem.rs
new file mode 100644 (file)
index 0000000..6dc2ff4
--- /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:coherence-lib.rs
+
+extern crate "coherence-lib" as lib;
+use lib::Remote1;
+
+struct Foo<T>(T);
+
+impl<T,U> Remote1<U> for Foo<T> { }
+
+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 5e028d3774fc50d4c7c06edd1bc204e8a5600ae2..e846501be6ee5fc64854843b5ad73a0b929e3fe2 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 use std::{str, string};
-use std::c_str::ToCStr;
 
 const A: [u8; 2] = ['h' as u8, 'i' as u8];
 const B: &'static [u8; 2] = &A;
@@ -19,12 +18,7 @@ pub fn main() {
     unsafe {
         let foo = &A as *const u8;
         assert_eq!(str::from_utf8_unchecked(&A), "hi");
-        assert_eq!(String::from_raw_buf_len(foo, A.len()), "hi".to_string());
-        assert_eq!(String::from_raw_buf_len(C, B.len()), "hi".to_string());
         assert!(*C == A[0]);
         assert!(*(&B[0] as *const u8) == A[0]);
-
-        let bar = str::from_utf8_unchecked(&A).to_c_str();
-        assert_eq!(bar.as_str(), "hi".to_c_str().as_str());
     }
 }
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 0e0ed1f436c9a019829452f680d963d00629e484..0a12df53de2327013b9e5f7d41c9fb2794a0edbd 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test that a custom deref with a fat pointer return type does not ICE
 
-#![feature(associated_types)]
-
 use std::ops::{Deref, DerefMut};
 
 pub struct Arr {
index a39670a27b9678e373f63b3c554d175f6e85f800..8ef8f1a868d51650f976fbdd5a8e1df479bce72e 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test that a custom deref with a fat pointer return type does not ICE
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 pub struct Arr {
index 6a69bfc248f16ec5794a31073657ebb1487f326c..d1823359af1351c438d6fd425c7752aafdf13316 100644 (file)
@@ -11,8 +11,6 @@
 // Test that overloaded index expressions with DST result types
 // work and don't ICE.
 
-#![feature(associated_types)]
-
 use std::ops::Index;
 use std::fmt::Show;
 
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 31ed212db999c7eb832c8eb6cbab94d1d9f128ca..2dcf6bf6d090757d0bd84950c8ea7358d08928ba 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 #[derive(PartialEq)]
 struct Bar;
 struct Baz;
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 b960a31bc0c71d636df79dd795f2b221d0a93837..da0a3e9e107e6cad55d8a7f935b0fa73e50d5aeb 100644 (file)
@@ -1,4 +1,3 @@
-
 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -14,8 +13,6 @@
 
 // Modified to not use export since it's going away. --pcw
 
-#![feature(globs)]
-
 mod foo {
     use foo::bar::*;
     pub mod bar {
index 8fb3893e5decfa8b051eb2848a562231a7cdd29c..a673a67089a3a2289225b0572a44b05ea52cb3cd 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::{Deref, DerefMut};
 
 // Generic unique/owned smaht pointer.
@@ -55,4 +53,3 @@ fn test2(mut x: Own<Own<Own<Point>>>) {
 }
 
 fn main() {}
-
index 8a75fdd685dd1055fb2515d5372182a30cb50cee..dff1a1eaa0473aaf7b3a3225051da1d5072ad8ff 100644 (file)
@@ -11,7 +11,7 @@
 // ignore-fast doesn't like extern crate
 
 extern crate libc;
-use std::c_str::ToCStr;
+use std::ffi::CString;
 
 mod mlibc {
     use libc::{c_char, size_t};
@@ -24,11 +24,10 @@ mod mlibc {
 
 fn strlen(str: String) -> uint {
     // C string is terminated with a zero
-    str.as_slice().with_c_str(|buf| {
-        unsafe {
-            mlibc::my_strlen(buf) as uint
-        }
-    })
+    let s = CString::from_slice(str.as_bytes());
+    unsafe {
+        mlibc::my_strlen(s.as_ptr()) as uint
+    }
 }
 
 pub fn main() {
index bb956b9ed89018ba895c4877d65727006110d402..ed8c6e73255bb49dba6d56d7076a1798b1d5aceb 100644 (file)
@@ -10,8 +10,6 @@
 
 // aux-build:default_type_params_xc.rs
 
-#![feature(default_type_params)]
-
 extern crate default_type_params_xc;
 
 struct Vec<T, A = default_type_params_xc::Heap>;
index e88801f14ed4839fa2015757324139f91d19916f..5ec478d39e34fd90140171c6aa72f4e564f7e577 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 struct Foo<A = (int, char)> {
     a: A
 }
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 44d98852054115d4131425c05265f7c6dfebff6a..a57b8de629eb54d14a46e014ec35795d789495e3 100644 (file)
@@ -1,4 +1,3 @@
-
 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -9,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
-
 use module_of_many_things::*;
 use dug::too::greedily::and::too::deep::*;
 
index 5ffcbb7e0fdd934d0da8cf5497ff91d917cba183..24d90741bbca4c5a45319d1b10197363bf8468a6 100644 (file)
@@ -1,4 +1,3 @@
-
 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -9,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
 #![allow(dead_assignment)]
 
 use std::mem::*;
index 19300569d2050cd6c24e37babcf38f959efe5376..3c28354dedcada0355805aa7bb053f4cc3fdb97e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
-
 pub fn main() {
     use std::mem::replace;
     let mut x = 5i;
index 5121e2185cb7ba2eb0d06adb3c0d2dd77e9fe9af..2b0f7cc7d7d3214dad905b149475b645f79303ac 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs, intrinsics)]
+#![feature(intrinsics)]
 
 mod rusti {
     extern "rust-intrinsic" {
index 9f2fe155cdf9597f1f48069cb3aaf78ea3c1102c..ed88b3c65e09c8f428c3740c77e693a0a9b82c2e 100644 (file)
@@ -9,16 +9,16 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs, 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 f9d79567932971a6569347f1f9dd91656ef4ebc8..4a07b5fc432c2bd99770e7cc59877eb09a695e6d 100644 (file)
@@ -15,8 +15,6 @@
 // when this bug was opened. The cases where the compiler
 // panics before the fix have a comment.
 
-#![feature(default_type_params)]
-
 use std::thunk::Thunk;
 
 struct S {x:()}
index ee556ce2c84595bad3f81337035e1fa0effcdfd6..21b54ba0e793b2807261ac09ac89a8c7694fea8e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::slice;
 
 pub struct PhfMapEntries<'a, T: 'a> {
index 00b508ab92c30e1a4acc194e0621e25f726342a1..3c76a827fb2958e546f145bd2e865bc489602b7e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 struct Root {
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 d5590e99f2cb994ac6f9f8c814062dc630d4d55b..21bda93ecec650f978b4b35f42cfa4b58e813377 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Matcher {
     fn next_match(&mut self) -> Option<(uint, uint)>;
 }
index 9796322b264c9263d9a98a8478d5854d768410fa..549ed08aaf37a54130f49bcf1c6e3dbd4ba74416 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 pub type BigRat<T = int> = T;
 
 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 f261098f5381137e684f3faa8ca21af40a4b08bb..e404f5fa11874e71fea79a36064e9fbd0308ed6b 100644 (file)
@@ -11,7 +11,7 @@
 // If `Index` used an associated type for its output, this test would
 // work more smoothly.
 
-#![feature(associated_types, old_orphan_check)]
+#![feature(old_orphan_check)]
 
 use std::ops::Index;
 
index 7bc6d989fa75cd5ce680c21c8061f6ff4cd80ad6..e01de3a3262edefbe1f725de31b0c2839ee95f18 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait MatrixRow {}
 
 struct Mat;
index da1cf0a38ca1c086a3944f7f0a4583d9b6d93d5e..72e948e613b2e2b70f2cd2b1362bc06003186cd4 100644 (file)
@@ -11,8 +11,6 @@
 // compile-flags:--test
 // ignore-pretty turns out the pretty-printer doesn't handle gensym'd things...
 
-#![feature(globs)]
-
 mod test {
     use super::*;
 
index 45cfabcd872ec653d176c00f009416f5b08372b8..6ef4f868d215094faf76c687bd6be2ec5949d4d2 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types, unboxed_closures)]
+#![feature(unboxed_closures)]
 
 use std::ops::{Deref, DerefMut};
 
index 45d3b53132dbf52d4f4c920a2356061ef5614de5..b4bd55da597578a8b2ca860b3eba0137406b7489 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
 trait Person {
     type string;
 }
index 49b03a974d868eaaa3d2f066d60a8d5ed730b3b8..da6c83142eab62c3a20244c07b8b4354adc93bbe 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params, unboxed_closures)]
+#![feature(unboxed_closures)]
 
 use std::thunk::Thunk;
 
diff --git a/src/test/run-pass/issue-17904.rs b/src/test/run-pass/issue-17904.rs
new file mode 100644 (file)
index 0000000..3ce347d
--- /dev/null
@@ -0,0 +1,18 @@
+// 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.
+
+struct Foo<T> where T: Copy;
+struct Bar<T>(T) where T: Copy;
+struct Bleh<T, U>(T, U) where T: Copy, U: Sized;
+struct Baz<T> where T: Copy {
+    field: T
+}
+
+fn main() {}
index aa95856a8b5ba812093e6a5414d2772b8dfc73b3..a2152db6884ac9fd269c26296cf286d438e85f22 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params, unboxed_closures)]
+#![feature(unboxed_closures)]
 
 use std::thunk::Thunk;
 
index e82359bc168e671f12e584cc156fce55293c4c16..11ffb4198dad8c6b838a3ad1f0dcab79eb4ba9d5 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub trait Borrow<Sized? Borrowed> {
+pub trait Borrow<Borrowed: ?Sized> {
         fn borrow(&self) -> &Borrowed;
 }
 
index 57724ba91b02f317e9a3e05ef067d7596f4143be..83ba322ba30134d0580affe0d79308742ef92c20 100644 (file)
@@ -10,8 +10,6 @@
 
 // ignore-pretty -- FIXME(#17362) pretty prints as `Hash<<Self as Hasher...` which fails to parse
 
-#![feature(associated_types)]
-
 pub trait Hasher {
     type State;
 
index 79afb856be26fce01c2f50d15ea59f236e296157..d95f74ef2a2ba8217c4b5ee48e5b5253240444b5 100644 (file)
@@ -11,8 +11,6 @@
 // Test that a partially specified trait object with unspecified associated
 // type does not ICE.
 
-#![feature(associated_types)]
-
 trait Foo {
     type A;
 }
index eecc073b0478232c859533166238ebd71c3749f3..3436871b4d1fef7f16331e5b8041ef09e454faec 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Trait<Input> {
     type Output;
 
index aeaf5e3764459466139e5fc488a35f04bcb1cd5b..d6b3a1908b82d6cb78b2619126ac7e56191199ef 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Trait<Input> {
     type Output;
 
index b3354530a0c3889cd0ffd61247119815fba1cb08..91bc645b2d486a4a2bce680b492d399af05e29ab 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
 trait Base {}
 trait AssocA {
     type X: Base;
index d036bab99f8801b56c2b2365077b8c21692625d9..43116f63641ded4b5e868cce3731a7fc33e0a4a3 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait PoolManager {
     type C;
 }
index 9bc74e5017305d8ce7544a7a9898dc5c86cb108a..01a073a6889aedf28a7fee91eaa3e1f09d4ef3a2 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait PoolManager {
     type C;
 }
index cd56fe186892437db61ef0f8aaa40013dcfb3fc3..a9ce6c7a9eb48bc7f399de8ecd60d20aae7ee8d8 100644 (file)
@@ -11,8 +11,6 @@
 // Test that `<Type as Trait>::Output` and `Self::Output` are accepted as type annotations in let
 // bindings
 
-#![feature(associated_types)]
-
 trait Int {
     fn one() -> Self;
     fn leading_zeros(self) -> uint;
index 535538793d1cf5177baef0be835a8e2e84e6df52..374460487d8f211dead321386806720688fe59ab 100644 (file)
@@ -10,8 +10,6 @@
 
 // Check that associated types are `Sized`
 
-#![feature(associated_types)]
-
 trait Trait {
     type Output;
 
index 0ef14149c94301ccf6720a630c9fc7116b33bd65..877cec48b5dc77c54e72542dd48e4f01df9ec246 100644 (file)
@@ -10,7 +10,6 @@
 
 // aux-build:issue_20389.rs
 
-#![feature(associated_types)]
 extern crate issue_20389;
 
 struct Foo;
index a8cbb0911b8ab9aaa20f16c7784792751d5c2d64..18c59dc9adc8e828b05dd79d570aa3a57042b0b8 100644 (file)
@@ -10,7 +10,6 @@
 
 // aux-build:issue-2526.rs
 
-#![feature(globs)]
 #![allow(unused_imports)]
 
 extern crate issue_2526;
index b89ee81a7274fdf026f5415f7aed924e4253dd2d..c3cfaf22dee05607b61e269bf86760f62768d7a2 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(default_type_params)]
-
 use std::thread::Thread;
 use std::sync::mpsc::Sender;
 use std::thunk::Invoke;
index 741f168482da2b11fd589af018de961b5a4d2e2a..43852fb33240090ddadb1314559108aa80ad0d64 100644 (file)
@@ -10,7 +10,7 @@
 
 // If `Mul` used an associated type for its output, this test would
 // work more smoothly.
-#![feature(associated_types, default_type_params, old_orphan_check)]
+#![feature(old_orphan_check)]
 
 use std::ops::Mul;
 
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 39b0711721b54a5abccfadd47447c0d7b28f8503..0ff265e483efe226a29873ce9a495c3ad9822ddf 100644 (file)
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
 #![allow(unused_imports, dead_code)]
 
 mod test1 {
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 {
diff --git a/src/test/run-pass/method-normalize-bounds-issue-20604.rs b/src/test/run-pass/method-normalize-bounds-issue-20604.rs
new file mode 100644 (file)
index 0000000..7348994
--- /dev/null
@@ -0,0 +1,65 @@
+// 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.
+
+// Test that we handle projection types which wind up important for
+// resolving methods. This test was reduced from a larger example; the
+// call to `foo()` at the end was failing to resolve because the
+// winnowing stage of method resolution failed to handle an associated
+// type projection.
+
+#![feature(associated_types)]
+
+trait Hasher {
+    type Output;
+    fn finish(&self) -> Self::Output;
+}
+
+trait Hash<H: Hasher> {
+    fn hash(&self, h: &mut H);
+}
+
+trait HashState {
+    type Wut: Hasher;
+    fn hasher(&self) -> Self::Wut;
+}
+
+struct SipHasher;
+impl Hasher for SipHasher {
+    type Output = u64;
+    fn finish(&self) -> u64 { 4 }
+}
+
+impl Hash<SipHasher> for int {
+    fn hash(&self, h: &mut SipHasher) {}
+}
+
+struct SipState;
+impl HashState for SipState {
+    type Wut = SipHasher;
+    fn hasher(&self) -> SipHasher { SipHasher }
+}
+
+struct Map<S> {
+    s: S,
+}
+
+impl<S> Map<S>
+    where S: HashState,
+          <S as HashState>::Wut: Hasher<Output=u64>,
+{
+    fn foo<K>(&self, k: K) where K: Hash< <S as HashState>::Wut> {}
+}
+
+fn foo<K: Hash<SipHasher>>(map: &Map<SipState>) {
+    map.foo(22);
+}
+
+fn main() {}
+
index 4e4fb75b428cc84f055a3a59a953b86f9771b488..e81244d4beabc20c1b9a1269db02b6c97b367180 100644 (file)
@@ -16,7 +16,7 @@
 use std::kinds::Sized;
 
 // Note: this must be generic for the problem to show up
-trait Foo<A> for ?Sized {
+trait Foo<A> {
     fn foo(&self);
 }
 
diff --git a/src/test/run-pass/method-where-clause.rs b/src/test/run-pass/method-where-clause.rs
new file mode 100644 (file)
index 0000000..4361c22
--- /dev/null
@@ -0,0 +1,42 @@
+// 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.
+
+// Test that we can use method notation to call methods based on a
+// where clause type, and not only type parameters.
+
+trait Foo {
+    fn foo(&self) -> int;
+}
+
+impl Foo for Option<int>
+{
+    fn foo(&self) -> int {
+        self.unwrap_or(22)
+    }
+}
+
+impl Foo for Option<uint>
+{
+    fn foo(&self) -> int {
+        self.unwrap_or(22) as int
+    }
+}
+
+fn check<T>(x: Option<T>) -> (int, int)
+    where Option<T> : Foo
+{
+    let y: Option<T> = None;
+    (x.foo(), y.foo())
+}
+
+fn main() {
+    assert_eq!(check(Some(23u)), (23i, 22i));
+    assert_eq!(check(Some(23i)), (23i, 22i));
+}
index 676fe6500818e37f01b2ba6eee9face47eb098bc..e4a8ec19eb8e84ce231739a702cff4bf956f3e92 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.
-#![feature(globs)]
 
 pub use Foo::*;
 use nest::{Bar, D, E, F};
index cc4985927f19025a16c6c9b3a94c5699c0498d44..e5317c2f57302ae63ee84e3ff237f5a18ee783b1 100644 (file)
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 // aux-build:namespaced_enums.rs
-#![feature(globs)]
 
 extern crate namespaced_enums;
 
index 137dd543566bd748531c17bcb2e66d65a6424ba4..c48be3af248f0982577fa3671a5ee3712b8dd168 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.
-#![feature(globs)]
 
 mod m2 {
     pub enum Foo {
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]) }
index 5999840091967a27f825d80ccf825efdb02329ca..8e5750005e2e9e60f88597d555daf90a488bb206 100644 (file)
@@ -11,8 +11,6 @@
 // Test that we can overload the `+` operator for points so that two
 // points can be added, and a point can be added to an integer.
 
-#![feature(associated_types, default_type_params)]
-
 use std::ops;
 
 #[derive(Show,PartialEq,Eq)]
index 41e7586f1e3db33fbe45341dea110152dbb7ccbd..c20b7336deb325e3a2f27240d7cbc30f02951b4e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::cmp;
 use std::ops;
 
index e9eb924d4493dc0817022e33607873f2bc7ed902..f0646853b6be8824223ea0c3a551ff736992d2dc 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::cell::Cell;
 use std::ops::{Deref, DerefMut};
 
index 6d8d09b321ee540b0c3bc72ea559983ae104be47..de37173810f044d0d4cb1dd1946d29d8a305a98e 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 struct DerefArray<'a, T:'a> {
index cafb665fc370d1e5a072d9592ea3ae8ce1a5acd9..c34aed42c970fe5e4120e40a86910e222b700b00 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::rc::Rc;
 use std::ops::Deref;
 
index 23efba157495c4a11dc3cc83c55b0f134cbca178..be2b309b8217ffa78f8931ceff6925ea25c03b4b 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::Deref;
 
 struct DerefWithHelper<H, T> {
index b3c9ec3dc934e3bee2b9a1bd409d9b5262f2f94a..56887636d5dfbc9baa8ffa62d889482be7c2b1f8 100644 (file)
@@ -10,7 +10,7 @@
 
 // Tests that nested vtables work with overloaded calls.
 
-#![feature(default_type_params, unboxed_closures)]
+#![feature(unboxed_closures)]
 
 use std::ops::Fn;
 use std::ops::Add;
@@ -27,4 +27,3 @@ fn main() {
     // ICE trigger
     G(1i);
 }
-
index b6fb38d5cc2cfd0520c55b327fc3c07f0cfe9765..5cd76879798cb77e14f96f658377269f21c84915 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::cell::Cell;
 use std::ops::{Deref, DerefMut};
 use std::vec::Vec;
index 77bb981cfd9b9a3f0fe06d389a9402c4cd4a1197..aac0b5e06d004fde8c98838ea36752d4425d4155 100644 (file)
@@ -11,8 +11,6 @@
 // Test overloading of the `[]` operator.  In particular test that it
 // takes its argument *by reference*.
 
-#![feature(associated_types)]
-
 use std::ops::Index;
 
 struct AssociationList<K,V> {
index d141234287d13e8e4452485329b144d22647b29a..bc67c0afc7b520d5f6e2b87d28f9bfad4ec865d3 100644 (file)
@@ -10,8 +10,6 @@
 
 // Test overloaded indexing combined with autoderef.
 
-#![feature(associated_types)]
-
 use std::ops::{Index, IndexMut};
 
 struct Foo {
@@ -84,4 +82,3 @@ fn main() {
     assert_eq!(f[1].get(), 5);
     assert_eq!(f[1].get_from_ref(), 5);
 }
-
index 9c6afc0912d0630a471b30bcfb782c30f08fedd9..487fb93c9fee8f3a09135d7503989ade445b6158 100644 (file)
@@ -11,8 +11,6 @@
 // Test using overloaded indexing when the "map" is stored in a
 // field. This caused problems at some point.
 
-#![feature(associated_types)]
-
 use std::ops::Index;
 
 struct Foo {
@@ -55,4 +53,3 @@ fn main() {
     } };
     assert_eq!(f.foo[1].get(), 2);
 }
-
index fe09b47cf0a789bbb707b2c16d0baf15be8e6ecc..0afdb24a81cc0dbf64dd86b437faeb4af54fa4bd 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::ops::{Index, IndexMut};
 
 struct Foo {
@@ -75,4 +73,3 @@ fn main() {
     assert_eq!(f[1].get(), 5);
     assert_eq!(f[1].get_from_ref(), 5);
 }
-
index 8a68711a769fc2e5a5ab1b3e2a13a1b65c669946..5649c4c784dafdab7a19cb563ab3dbe76e10a544 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 trait Foo {
     type T;
     fn foo() -> Box<<Self as Foo>::T>;
diff --git a/src/test/run-pass/parse-complex-macro-invoc-op.rs b/src/test/run-pass/parse-complex-macro-invoc-op.rs
new file mode 100644 (file)
index 0000000..e9ec624
--- /dev/null
@@ -0,0 +1,43 @@
+// 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.
+
+// Test parsing binary operators after macro invocations.
+
+#![feature(macro_rules)]
+
+macro_rules! id {
+    ($e: expr) => { $e }
+}
+
+fn foo() {
+    id!(1i) + 1;
+    id![1i] - 1;
+    id!(1i) * 1;
+    id![1i] / 1;
+    id!(1i) % 1;
+
+    id!(1i) & 1;
+    id![1i] | 1;
+    id!(1i) ^ 1;
+
+    let mut x = 1i;
+    id![x] = 2;
+    id!(x) += 1;
+
+    id!(1f64).clone();
+
+    id!([1i, 2, 3])[1];
+    id![drop](1i);
+
+    id!(true) && true;
+    id![true] || true;
+}
+
+fn main() {}
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 336791e65fdee24d151b9b4de5c78f510b2d41ac..f3380352f5fa946c96a52c215461adffebb508eb 100644 (file)
@@ -12,7 +12,6 @@
 // Check we do the correct privacy checks when we import a name and there is an
 // item with that name in both the value and type namespaces.
 
-#![feature(globs)]
 #![allow(dead_code)]
 #![allow(unused_imports)]
 
@@ -115,4 +114,3 @@ fn test_glob3() {
 
 fn main() {
 }
-
index 8de88aacae7fc0104a98e338d91897233c8edaad..22ca737d421987ac99cfe78fcc3b5c17083b3543 100644 (file)
@@ -1,4 +1,3 @@
-
 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -9,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
 
 mod a {
     pub fn f() {}
index d52c1c0b12c536b0e89b972bdec07c9ff3cda00e..d3464f01203ac5f3adb5cb24587be0eb7ff622aa 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types, unsafe_destructor)]
+#![feature(unsafe_destructor)]
 
 pub struct Foo<T>;
 
diff --git a/src/test/run-pass/regions-reassign-let-bound-pointer.rs b/src/test/run-pass/regions-reassign-let-bound-pointer.rs
new file mode 100644 (file)
index 0000000..ecf79de
--- /dev/null
@@ -0,0 +1,23 @@
+// 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.
+
+// Check that the type checker permits us to reassign `z` which
+// started out with a longer lifetime and was reassigned to a shorter
+// one (it should infer to be the intersection).
+
+fn foo(x: &int) {
+    let a = 1;
+    let mut z = x;
+    z = &a;
+}
+
+pub fn main() {
+    foo(&1);
+}
diff --git a/src/test/run-pass/regions-reassign-match-bound-pointer.rs b/src/test/run-pass/regions-reassign-match-bound-pointer.rs
new file mode 100644 (file)
index 0000000..18312b1
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+
+// Check that the type checker permits us to reassign `z` which
+// started out with a longer lifetime and was reassigned to a shorter
+// one (it should infer to be the intersection).
+
+fn foo(x: &int) {
+    let a = 1;
+    match x {
+        mut z => {
+            z = &a;
+        }
+    }
+}
+
+pub fn main() {
+    foo(&1);
+}
diff --git a/src/test/run-pass/regions-relate-bound-regions-on-closures-to-inference-variables.rs b/src/test/run-pass/regions-relate-bound-regions-on-closures-to-inference-variables.rs
new file mode 100644 (file)
index 0000000..2bdc883
--- /dev/null
@@ -0,0 +1,65 @@
+// 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.
+
+// Test that this fairly specialized, but also reasonable, pattern
+// typechecks. The pattern involves regions bound in closures that
+// wind up related to inference variables.
+//
+// NB. Changes to the region implementatiosn have broken this pattern
+// a few times, but it happens to be used in the compiler so those
+// changes were caught. However, those uses in the compiler could
+// easily get changed or refactored away in the future.
+
+struct Ctxt<'tcx> {
+    x: &'tcx Vec<int>
+}
+
+struct Foo<'a,'tcx:'a> {
+    cx: &'a Ctxt<'tcx>,
+}
+
+impl<'a,'tcx> Foo<'a,'tcx> {
+    fn bother(&mut self) -> int {
+        self.elaborate_bounds(box |this| {
+            // (*) Here: type of `this` is `&'f0 Foo<&'f1, '_2>`,
+            // where `'f0` and `'f1` are fresh, free regions that
+            // result from the bound regions on the closure, and `'2`
+            // is a region inference variable created by the call. Due
+            // to the constraints on the type, we find that `'_2 : 'f1
+            // + 'f2` must hold (and can be assumed by the callee).
+            // Region inference has to do some clever stuff to avoid
+            // inferring `'_2` to be `'static` in this case, because
+            // it is created outside the closure but then related to
+            // regions bound by the closure itself. See the
+            // `region_inference.rs` file (and the `givens` field, in
+            // particular) for more details.
+            this.foo()
+        })
+    }
+
+    fn foo(&mut self) -> int {
+        22
+    }
+
+    fn elaborate_bounds(
+        &mut self,
+        mut mk_cand: Box<for<'b> FnMut(&mut Foo<'b, 'tcx>) -> int>)
+        -> int
+    {
+        mk_cand(self)
+    }
+}
+
+fn main() {
+    let v = vec!();
+    let cx = Ctxt { x: &v };
+    let mut foo = Foo { cx: &cx };
+    assert_eq!(foo.bother(), 22); // just so the code is not dead, basically
+}
index c7aa405b513e465bb6404d80d57df928edb5e95b..d610bf09edb958b0503c7795b95f6011cd1a1b18 100644 (file)
@@ -13,8 +13,8 @@
 
 extern crate libc;
 
+use std::ffi::CString;
 use std::io::TempDir;
-use std::c_str::ToCStr;
 use std::io::fs::PathExtensions;
 use std::io::fs;
 use std::io;
@@ -31,20 +31,17 @@ fn rename_directory() {
         let test_file = &old_path.join("temp.txt");
 
         /* Write the temp input file */
-        let ostream = test_file.with_c_str(|fromp| {
-            "w+b".with_c_str(|modebuf| {
-                libc::fopen(fromp, modebuf)
-            })
-        });
+        let fromp = CString::from_slice(test_file.as_vec());
+        let modebuf = CString::from_slice(b"w+b");
+        let ostream = libc::fopen(fromp.as_ptr(), modebuf.as_ptr());
         assert!((ostream as uint != 0u));
         let s = "hello".to_string();
-        "hello".with_c_str(|buf| {
-            let write_len = libc::fwrite(buf as *const libc::c_void,
-                                         1u as libc::size_t,
-                                         (s.len() + 1u) as libc::size_t,
-                                         ostream);
-            assert_eq!(write_len, (s.len() + 1) as libc::size_t)
-        });
+        let buf = CString::from_slice(b"hello");
+        let write_len = libc::fwrite(buf.as_ptr() as *mut _,
+                                     1u as libc::size_t,
+                                     (s.len() + 1u) as libc::size_t,
+                                     ostream);
+        assert_eq!(write_len, (s.len() + 1) as libc::size_t);
         assert_eq!(libc::fclose(ostream), (0u as libc::c_int));
 
         let new_path = tmpdir.join_many(&["quux", "blat"]);
index fc53737bb445a587e5feee24febe5bb4e823aafe..6f807fc34995eaae94270d5318b3abe647788454 100644 (file)
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use std::ffi;
 use std::io::process::{Command, ProcessOutput};
 use std::os;
 use std::rt::unwind::try;
@@ -34,7 +35,8 @@ fn start(argc: int, argv: *const *const u8) -> int {
 
     let args = unsafe {
         range(0, argc as uint).map(|i| {
-            String::from_raw_buf(*argv.offset(i as int)).into_bytes()
+            let ptr = *argv.offset(i as int) as *const _;
+            ffi::c_str_to_bytes(&ptr).to_vec()
         }).collect::<Vec<_>>()
     };
     let me = args[0].as_slice();
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 ceb6b790426812b150d8538264946376991a6e5d..e89d5c9922dfafce12ab7e7c2753bf1a071462d6 100644 (file)
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 
-#![feature(associated_types, simd)]
+#![feature(simd)]
 
 use std::ops;
 
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 2177ab01db9c3f8c1988e04073100b6b5df609b6..2eff97d31b25d4875a39ce06c9127b2f9b8a51c8 100644 (file)
@@ -1,4 +1,3 @@
-
 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
 // file at the top-level directory of this distribution and at
 // http://rust-lang.org/COPYRIGHT.
@@ -9,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(globs)]
 
 use alder::*;
 
index 6812255d82ca0f4e8c0a8a2f97a257443fcb932c..4ab089b6eaa1c8420d34414cf1305e956041a509 100644 (file)
@@ -16,7 +16,6 @@
 // one test task to ensure that errors are timeouts, not file descriptor
 // exhaustion.
 
-#![feature(macro_rules, globs)]
 #![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;
 
index 33e10cc77b7c1d757773e991981c42c45a2f723e..bf108ecd6764a954e681940487786c1e78a21382 100644 (file)
@@ -29,7 +29,7 @@ fn test_tempdir() {
     let path = {
         let p = TempDir::new_in(&Path::new("."), "foobar").unwrap();
         let p = p.path();
-        assert!(p.as_vec().ends_with(b"foobar"));
+        assert!(p.as_str().unwrap().contains("foobar"));
         p.clone()
     };
     assert!(!path.exists());
index 3e8db61b94044badc065d4313a9a3e8586bca117..43494458518cd9205e2ecaac2d195fe3882d41b8 100644 (file)
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(associated_types)]
-
 use std::cmp::PartialEq;
 use std::ops::{Add, Sub, Mul};
 
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);
 
index 07b9fac66554e0730ba063c5fe9f924ce4e07539..e6dd8d46952eb4b1627ceef0ac3d70bde9fd5d39 100644 (file)
@@ -12,9 +12,9 @@
 
 // Test syntax checks for `?Sized` syntax.
 
-trait T1 for ?Sized {}
-pub trait T2 for ?Sized {}
-trait T3<X: T1> for ?Sized: T2 {}
+trait T1 {}
+pub trait T2 {}
+trait T3<X: T1> : T2 {}
 trait T4<X: ?Sized> {}
 trait T5<X: ?Sized, Y> {}
 trait T6<Y, X: ?Sized> {}
index 8d2c99d4414c9921bf2110f15c86ac1a7ba3ceaf..c7e8b2a05ec5b697bf68ebcbd92b6b29c060763f 100644 (file)
@@ -22,7 +22,7 @@ fn f2<X>(x: &X) {
 }
 
 // Bounded.
-trait T for ?Sized {}
+trait T {}
 fn f3<X: T+?Sized>(x: &X) {
     f3::<X>(x);
 }
@@ -32,7 +32,7 @@ fn f4<X: T>(x: &X) {
 }
 
 // Self type.
-trait T2 for ?Sized {
+trait T2 {
     fn f() -> Box<Self>;
 }
 struct S;
@@ -48,7 +48,7 @@ fn f6<X: T2>(x: &X) {
     let _: Box<X> = T2::f();
 }
 
-trait T3 for ?Sized {
+trait T3 {
     fn f() -> Box<Self>;
 }
 impl T3 for S {
index 3e7718970258f4362964e3536e8264fb53b5591f..9600a242ca109d57fdc47a5640f2f088621af40f 100644 (file)
@@ -10,7 +10,7 @@
 
 extern crate libc;
 
-use std::c_str::{CString, ToCStr};
+use std::ffi::{self, CString};
 use libc::{c_char, c_int};
 
 // ignore-fast doesn't like extern crate
 unsafe fn check<T, F>(expected: &str, f: F) where F: FnOnce(*mut c_char) -> T {
     let mut x = [0 as c_char; 50];
     f(&mut x[0] as *mut c_char);
-    let res = CString::new(&x[0], false);
-    assert_eq!(expected, res.as_str().unwrap());
+    assert_eq!(expected.as_bytes(), ffi::c_str_to_bytes(&x.as_ptr()));
 }
 
 pub fn main() {
 
     unsafe {
         // Call with just the named parameter
-        "Hello World\n".with_c_str(|c| {
-            check("Hello World\n", |s| sprintf(s, c));
-        });
+        let c = CString::from_slice(b"Hello World\n");
+        check("Hello World\n", |s| sprintf(s, c.as_ptr()));
 
         // Call with variable number of arguments
-        "%d %f %c %s\n".with_c_str(|c| {
-            check("42 42.500000 a %d %f %c %s\n\n", |s| {
-                sprintf(s, c, 42i, 42.5f64, 'a' as c_int, c);
-            })
+        let c = CString::from_slice(b"%d %f %c %s\n");
+        check("42 42.500000 a %d %f %c %s\n\n", |s| {
+            sprintf(s, c.as_ptr(), 42i, 42.5f64, 'a' as c_int, c.as_ptr());
         });
 
         // Make a function pointer
-        let x: unsafe extern "C" fn(*mut c_char, *const c_char, ...) -> c_int = sprintf;
+        let x: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int = sprintf;
 
         // A function that takes a function pointer
-        unsafe fn call(p: unsafe extern "C" fn(*mut c_char, *const c_char, ...) -> c_int) {
-            // Call with just the named parameter via fn pointer
-            "Hello World\n".with_c_str(|c| {
-                check("Hello World\n", |s| p(s, c));
-            });
+        unsafe fn call(p: unsafe extern fn(*mut c_char, *const c_char, ...) -> c_int) {
+            // Call with just the named parameter
+            let c = CString::from_slice(b"Hello World\n");
+            check("Hello World\n", |s| sprintf(s, c.as_ptr()));
 
             // Call with variable number of arguments
-            "%d %f %c %s\n".with_c_str(|c| {
-                check("42 42.500000 a %d %f %c %s\n\n", |s| {
-                    p(s, c, 42i, 42.5f64, 'a' as c_int, c);
-                })
+            let c = CString::from_slice(b"%d %f %c %s\n");
+            check("42 42.500000 a %d %f %c %s\n\n", |s| {
+                sprintf(s, c.as_ptr(), 42i, 42.5f64, 'a' as c_int, c.as_ptr());
             });
         }
 
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..7b2c35a
--- /dev/null
@@ -0,0 +1,37 @@
+// 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]
+
+extern crate "std" as other;
+
+#[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;
+
+// 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();