auto merge of #12614 : alexcrichton/rust/rollup, r=alexcrichton

Closes #12546 (Add new target 'make dist-osx' to create a .pkg installer for OS X) r=brson
Closes #12575 (rustc: Move local native libs back in link-args) r=brson
Closes #12587 (Provide a more helpful error for tests that fail due to noexec) r=brson
Closes #12589 (rustc: Remove codemap and reachable from metadata encoder) r=alexcrichton
Closes #12591 (Fix syntax::ext::deriving{,::*} docs formatting.) r=huonw
Closes #12592 (Miscellaneous Vim improvements) r=alexcrichton
Closes #12596 (path: Implement windows::make_non_verbatim()) r=alexcrichton
Closes #12598 (Improve the ctags function regular expression) r=alexcrichton
Closes #12599 (Tutorial improvement (new variant of PR #12472).) r=pnkfelix
Closes #12603 (std: Export the select! macro) r=pcwalton
Closes #12605 (Fix typo in doc of Binary trait in std::fmt) r=alexcrichton
Closes #12613 (Fix bytepos_to_file_charpos) r=brson
This commit is contained in:
bors 2014-02-27 23:01:55 -08:00
commit 53e90c15a6
23 changed files with 407 additions and 98 deletions

View file

@ -12,6 +12,10 @@ PKG_ICO = $(S)src/etc/pkg/rust-logo.ico
PKG_EXE = $(PKG_DIR)-install.exe
endif
ifeq ($(CFG_OSTYPE), apple-darwin)
PKG_OSX = $(PKG_DIR).pkg
endif
PKG_GITMODULES := $(S)src/libuv $(S)src/llvm $(S)src/gyp $(S)src/compiler-rt
PKG_FILES := \
@ -41,10 +45,10 @@ PKG_FILES := \
UNROOTED_PKG_FILES := $(patsubst $(S)%,./%,$(PKG_FILES))
ifdef CFG_ISCC
LICENSE.txt: $(S)COPYRIGHT $(S)LICENSE-APACHE $(S)LICENSE-MIT
cat $^ > $@
ifdef CFG_ISCC
%.iss: $(S)src/etc/pkg/%.iss
cp $< $@
@ -103,7 +107,7 @@ distcheck: dist
else
dist: $(PKG_TAR)
dist: $(PKG_TAR) $(PKG_OSX)
distcheck: $(PKG_TAR)
$(Q)rm -Rf dist
@ -124,3 +128,31 @@ distcheck: $(PKG_TAR)
@echo -----------------------------------------------
endif
ifeq ($(CFG_OSTYPE), apple-darwin)
dist-prepare-osx: PREPARE_HOST=$(CFG_BUILD)
dist-prepare-osx: PREPARE_TARGETS=$(CFG_BUILD)
dist-prepare-osx: PREPARE_DEST_DIR=tmp/dist/pkgroot
dist-prepare-osx: PREPARE_STAGE=2
dist-prepare-osx: PREPARE_DIR_CMD=$(DEFAULT_PREPARE_DIR_CMD)
dist-prepare-osx: PREPARE_BIN_CMD=$(DEFAULT_PREPARE_BIN_CMD)
dist-prepare-osx: PREPARE_LIB_CMD=$(DEFAULT_PREPARE_LIB_CMD)
dist-prepare-osx: PREPARE_MAN_CMD=$(DEFAULT_PREPARE_MAN_CMD)
dist-prepare-osx: prepare-base
$(PKG_OSX): Distribution.xml LICENSE.txt dist-prepare-osx
@$(call E, making OS X pkg)
$(Q)pkgbuild --identifier org.rust-lang.rust --root tmp/dist/pkgroot rust.pkg
$(Q)productbuild --distribution Distribution.xml --resources . $(PKG_OSX)
$(Q)rm -rf tmp rust.pkg
dist-osx: $(PKG_OSX)
distcheck-osx: $(PKG_OSX)
@echo
@echo -----------------------------------------------
@echo $(PKG_OSX) ready for distribution
@echo -----------------------------------------------
endif

View file

@ -133,6 +133,10 @@ fn main() {
println!("hello?");
}
~~~~
> ***Note:*** An identifier followed by an exclamation point, like
> `println!`, is a macro invocation. Macros are explained
> [later](#syntax-extensions); for now just remember to include the
> exclamation point.
If the Rust compiler was installed successfully, running `rustc
hello.rs` will produce an executable called `hello` (or `hello.exe` on
@ -1059,7 +1063,7 @@ box, while the owner holds onto a pointer to it:
list -> | Cons | 1 | ~ | -> | Cons | 2 | ~ | -> | Cons | 3 | ~ | -> | Nil |
+--------------+ +--------------+ +--------------+ +--------------+
> Note: the above diagram shows the logical contents of the enum. The actual
> ***Note:*** the above diagram shows the logical contents of the enum. The actual
> memory layout of the enum may vary. For example, for the `List` enum shown
> above, Rust guarantees that there will be no enum tag field in the actual
> structure. See the language reference for more details.
@ -1114,7 +1118,7 @@ let z = x; // no new memory allocated, `x` can no longer be used
~~~~
The `clone` method is provided by the `Clone` trait, and can be derived for
our `List` type. Traits will be explained in detail later.
our `List` type. Traits will be explained in detail [later](#traits).
~~~{.ignore}
#[deriving(Clone)]
@ -1207,8 +1211,8 @@ let ys = Cons(5, ~Cons(10, ~Nil));
assert!(eq(&xs, &ys));
~~~
Note that Rust doesn't guarantee [tail-call](http://en.wikipedia.org/wiki/Tail_call) optimization,
but LLVM is able to handle a simple case like this with optimizations enabled.
> ***Note:*** Rust doesn't guarantee [tail-call](http://en.wikipedia.org/wiki/Tail_call) optimization,
> but LLVM is able to handle a simple case like this with optimizations enabled.
## Lists of other types
@ -1218,6 +1222,9 @@ element type.
The `u32` in the previous definition can be substituted with a type parameter:
> ***Note:*** The following code introduces generics, which are explained in a
> [dedicated section](#generics).
~~~
enum List<T> {
Cons(T, ~List<T>),
@ -1336,10 +1343,14 @@ impl<T: Eq> Eq for List<T> {
let xs = Cons(5, ~Cons(10, ~Nil));
let ys = Cons(5, ~Cons(10, ~Nil));
// The methods below are part of the Eq trait,
// which we implemented on our linked list.
assert!(xs.eq(&ys));
assert!(xs == ys);
assert!(!xs.ne(&ys));
assert!(!(xs != ys));
// The Eq trait also allows us to use the shorthand infix operators.
assert!(xs == ys); // `xs == ys` is short for `xs.eq(&ys)`
assert!(!(xs != ys)); // `xs != ys` is short for `xs.ne(&ys)`
~~~
# More on boxes

View file

@ -1,6 +1,6 @@
--langdef=Rust
--langmap=Rust:.rs
--regex-Rust=/^[ \t]*(pub[ \t]+)?fn[ \t]+([a-zA-Z0-9_]+)/\2/f,functions,function definitions/
--regex-Rust=/^[ \t]*(#\[[^\]]\][ \t]*)*(pub[ \t]+)?(extern[ \t]+)?("[^"]+"[ \t]+)?(unsafe[ \t]+)?fn[ \t]+([a-zA-Z0-9_]+)/\6/f,functions,function definitions/
--regex-Rust=/^[ \t]*(pub[ \t]+)?type[ \t]+([a-zA-Z0-9_]+)/\2/T,types,type definitions/
--regex-Rust=/^[ \t]*(pub[ \t]+)?enum[ \t]+([a-zA-Z0-9_]+)/\2/g,enum,enumeration names/
--regex-Rust=/^[ \t]*(pub[ \t]+)?struct[ \t]+([a-zA-Z0-9_]+)/\2/s,structure names/

View file

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<installer-gui-script minSpecVersion="2">
<title>Rust</title>
<license file="LICENSE.txt" mime-type="text/plain"/>
<pkg-ref id="org.rust-lang.rust"/>
<options customize="never" require-scripts="false" hostArchitectures="i386,x86_64"/>
<volume-check>
<allowed-os-versions>
<os-version min="10.7"/>
</allowed-os-versions>
</volume-check>
<choices-outline>
<line choice="default">
<line choice="org.rust-lang.rust"/>
</line>
</choices-outline>
<choice id="default"/>
<choice id="org.rust-lang.rust" visible="false">
<pkg-ref id="org.rust-lang.rust"/>
</choice>
<pkg-ref id="org.rust-lang.rust" version="0" onConclusion="none">rust.pkg</pkg-ref>
</installer-gui-script>

View file

@ -1,7 +1,7 @@
" Vim syntax file
" Language: Rust
" Maintainer: Chris Morgan <me@chrismorgan.info>
" Last Change: 2013 Jul 10
" Last Change: 2014 Feb 27
if exists("b:did_ftplugin")
finish
@ -42,4 +42,55 @@ if exists("g:loaded_delimitMate")
let b:delimitMate_excluded_regions = delimitMate#Get("excluded_regions") . ',rustLifetimeCandidate,rustGenericLifetimeCandidate'
endif
let b:undo_ftplugin = "setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd< | if exists('b:rust_original_delimitMate_excluded_regions') | let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions | unlet b:rust_original_delimitMate_excluded_regions | elseif exists('b:delimitMate_excluded_regions') | unlet b:delimitMate_excluded_regions | endif"
" Bind motion commands to support hanging indents
nnoremap <silent> <buffer> [[ :call <SID>Rust_Jump('n', 'Back')<CR>
nnoremap <silent> <buffer> ]] :call <SID>Rust_Jump('n', 'Forward')<CR>
xnoremap <silent> <buffer> [[ :call <SID>Rust_Jump('v', 'Back')<CR>
xnoremap <silent> <buffer> ]] :call <SID>Rust_Jump('v', 'Forward')<CR>
onoremap <silent> <buffer> [[ :call <SID>Rust_Jump('o', 'Back')<CR>
onoremap <silent> <buffer> ]] :call <SID>Rust_Jump('o', 'Forward')<CR>
let b:undo_ftplugin = "
\setlocal formatoptions< comments< commentstring< includeexpr< suffixesadd<
\|if exists('b:rust_original_delimitMate_excluded_regions')
\|let b:delimitMate_excluded_regions = b:rust_original_delimitMate_excluded_regions
\|unlet b:rust_original_delimitMate_excluded_regions
\|elseif exists('b:delimitMate_excluded_regions')
\|unlet b:delimitMate_excluded_regions
\|endif
\|nunmap <buffer> [[
\|nunmap <buffer> ]]
\|xunmap <buffer> [[
\|xunmap <buffer> ]]
\|ounmap <buffer> [[
\|ounmap <buffer> ]]
\"
if exists('*<SID>Rust_Jump') | finish | endif
function! <SID>Rust_Jump(mode, function) range
let cnt = v:count1
normal! m'
if a:mode ==# 'v'
norm! gv
endif
let foldenable = &foldenable
set nofoldenable
while cnt > 0
execute "call <SID>Rust_Jump_" . a:function . "()"
let cnt = cnt - 1
endwhile
let &foldenable = foldenable
endfunction
function! <SID>Rust_Jump_Back()
call search('{', 'b')
keepjumps normal! w99[{
endfunction
function! <SID>Rust_Jump_Forward()
normal! j0
call search('{', 'b')
keepjumps normal! w99[{%
call search('{')
endfunction

View 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: 2014 Feb 14
" Last Change: 2014 Feb 27
if version < 600
syntax clear
@ -18,8 +18,8 @@ syn keyword rustOperator as
syn match rustAssert "\<assert\(\w\)*!" contained
syn match rustFail "\<fail\(\w\)*!" contained
syn keyword rustKeyword break continue do
syn keyword rustKeyword extern nextgroup=rustExternCrate skipwhite
syn keyword rustKeyword break continue
syn keyword rustKeyword extern nextgroup=rustExternCrate,rustObsoleteExternMod skipwhite
syn keyword rustKeyword for in if impl let
syn keyword rustKeyword loop once priv pub
syn keyword rustKeyword return
@ -35,12 +35,13 @@ syn keyword rustObsoleteStorage const
syn keyword rustInvalidBareKeyword crate
syn keyword rustExternCrate crate contained nextgroup=rustIdentifier skipwhite
syn keyword rustObsoleteExternMod mod contained nextgroup=rustIdentifier skipwhite
syn match rustIdentifier contains=rustIdentifierPrime "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
syn match rustFuncName "\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" display contained
" Reserved (but not yet used) keywords {{{2
syn keyword rustReservedKeyword alignof be offsetof pure sizeof typeof yield
syn keyword rustReservedKeyword alignof be do offsetof pure sizeof typeof yield
" Built-in types {{{2
syn keyword rustType int uint float char bool u8 u16 u32 u64 f32
@ -51,8 +52,7 @@ syn keyword rustType f64 i8 i16 i32 i64 str Self
" to make it easy to update.
" Core operators {{{3
syn keyword rustTrait Sized
syn keyword rustTrait Freeze Send
syn keyword rustTrait Freeze Pod Send Sized
syn keyword rustTrait Add Sub Mul Div Rem Neg Not
syn keyword rustTrait BitAnd BitOr BitXor
syn keyword rustTrait Drop
@ -63,32 +63,25 @@ syn keyword rustEnum Result
syn keyword rustEnumVariant Ok Err
" Functions {{{3
"syn keyword rustFunction print println
"syn keyword rustFunction range
"syn keyword rustFunction from_str
"syn keyword rustFunction range
"syn keyword rustFunction drop
" Types and traits {{{3
syn keyword rustTrait Any AnyOwnExt AnyRefExt AnyMutRefExt
syn keyword rustTrait Ascii AsciiCast OwnedAsciiCast AsciiStr IntoBytes
syn keyword rustTrait Bool
syn keyword rustTrait ToCStr
syn keyword rustTrait Char
syn keyword rustTrait Clone DeepClone
syn keyword rustTrait Eq Ord TotalEq TotalOrd Ordering Equiv
syn keyword rustEnumVariant Less Equal Greater
syn keyword rustTrait Container Mutable Map MutableMap Set MutableSet
syn keyword rustTrait Default
syn keyword rustTrait Hash
syn keyword rustTrait FromStr
syn keyword rustTrait FromIterator Extendable
syn keyword rustTrait Iterator DoubleEndedIterator RandomAccessIterator CloneableIterator
syn keyword rustTrait OrdIterator MutableDoubleEndedIterator ExactSize
syn keyword rustTrait Algebraic Trigonometric Exponential Hyperbolic
syn keyword rustTrait Bitwise Bounded Fractional
syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul CheckedDiv
syn keyword rustTrait Orderable Signed Unsigned Round
syn keyword rustTrait Primitive Int Float ToStrRadix ToPrimitive FromPrimitive
syn keyword rustTrait Num NumCast CheckedAdd CheckedSub CheckedMul
syn keyword rustTrait Signed Unsigned Round
syn keyword rustTrait Primitive Int Float ToPrimitive FromPrimitive
syn keyword rustTrait GenericPath Path PosixPath WindowsPath
syn keyword rustTrait RawPtr
syn keyword rustTrait Buffer Writer Reader Seek
@ -98,20 +91,17 @@ syn keyword rustTrait Tuple1 Tuple2 Tuple3 Tuple4
syn keyword rustTrait Tuple5 Tuple6 Tuple7 Tuple8
syn keyword rustTrait Tuple9 Tuple10 Tuple11 Tuple12
syn keyword rustTrait ImmutableEqVector ImmutableTotalOrdVector ImmutableCloneableVector
syn keyword rustTrait OwnedVector OwnedCloneableVector OwnedEqVector MutableVector
syn keyword rustTrait OwnedVector OwnedCloneableVector OwnedEqVector
syn keyword rustTrait MutableVector MutableTotalOrdVector
syn keyword rustTrait Vector VectorVector CloneableVector ImmutableVector
"syn keyword rustFunction stream
syn keyword rustTrait Port Chan GenericChan GenericSmartChan GenericPort Peekable
syn keyword rustTrait Port Chan
"syn keyword rustFunction spawn
syn keyword rustSelf self
syn keyword rustBoolean true false
syn keyword rustConstant Some None " option
syn keyword rustConstant Ok Err " result
syn keyword rustConstant Less Equal Greater " Ordering
" Other syntax {{{2
" If foo::bar changes to foo.bar, change this ("::" to "\.").
@ -247,6 +237,7 @@ hi def link rustObsoleteStorage Error
hi def link rustLifetime Special
hi def link rustInvalidBareKeyword Error
hi def link rustExternCrate rustKeyword
hi def link rustObsoleteExternMod Error
" Other Suggestions:
" hi rustAttribute ctermfg=cyan

View file

@ -1132,8 +1132,41 @@ fn link_args(sess: Session,
args.push(~"-Wl,--allow-multiple-definition");
}
add_local_native_libraries(&mut args, sess);
// Take careful note of the ordering of the arguments we pass to the linker
// here. Linkers will assume that things on the left depend on things to the
// right. Things on the right cannot depend on things on the left. This is
// all formally implemented in terms of resolving symbols (libs on the right
// resolve unknown symbols of libs on the left, but not vice versa).
//
// For this reason, we have organized the arguments we pass to the linker as
// such:
//
// 1. The local object that LLVM just generated
// 2. Upstream rust libraries
// 3. Local native libraries
// 4. Upstream native libraries
//
// This is generally fairly natural, but some may expect 2 and 3 to be
// swapped. The reason that all native libraries are put last is that it's
// not recommended for a native library to depend on a symbol from a rust
// crate. If this is the case then a staticlib crate is recommended, solving
// the problem.
//
// Additionally, it is occasionally the case that upstream rust libraries
// depend on a local native library. In the case of libraries such as
// lua/glfw/etc the name of the library isn't the same across all platforms,
// so only the consumer crate of a library knows the actual name. This means
// that downstream crates will provide the #[link] attribute which upstream
// crates will depend on. Hence local native libraries are after out
// upstream rust crates.
//
// In theory this means that a symbol in an upstream native library will be
// shadowed by a local native library when it wouldn't have been before, but
// this kind of behavior is pretty platform specific and generally not
// recommended anyway, so I don't think we're shooting ourself in the foot
// much with that.
add_upstream_rust_crates(&mut args, sess, dylib, tmpdir);
add_local_native_libraries(&mut args, sess);
add_upstream_native_libraries(&mut args, sess);
// # Telling the linker what we're doing

View file

@ -40,7 +40,6 @@ use syntax::ast_util::*;
use syntax::ast_util;
use syntax::attr::AttrMetaMethods;
use syntax::attr;
use syntax::codemap;
use syntax::diagnostic::SpanHandler;
use syntax::parse::token::InternedString;
use syntax::parse::token::special_idents;
@ -73,8 +72,6 @@ pub struct EncodeParams<'a> {
link_meta: &'a LinkMeta,
cstore: @cstore::CStore,
encode_inlined_item: EncodeInlinedItem<'a>,
reachable: @RefCell<HashSet<ast::NodeId>>,
codemap: @codemap::CodeMap,
}
struct Stats {
@ -104,13 +101,6 @@ pub struct EncodeContext<'a> {
cstore: &'a cstore::CStore,
encode_inlined_item: EncodeInlinedItem<'a>,
type_abbrevs: abbrev_map,
reachable: @RefCell<HashSet<ast::NodeId>>,
codemap: @codemap::CodeMap,
}
pub fn reachable(ecx: &EncodeContext, id: NodeId) -> bool {
let reachable = ecx.reachable.borrow();
reachable.get().contains(&id)
}
fn encode_name(ebml_w: &mut writer::Encoder, name: Name) {
@ -1630,7 +1620,7 @@ impl<'a, 'b> Visitor<()> for MacroDefVisitor<'a, 'b> {
fn visit_item(&mut self, item: &Item, _: ()) {
match item.node {
ItemMac(..) => {
let def = self.ecx.codemap.span_to_snippet(item.span)
let def = self.ecx.tcx.sess.codemap.span_to_snippet(item.span)
.expect("Unable to find source for macro");
self.ebml_w.start_tag(tag_macro_def);
self.ebml_w.wr_str(def);
@ -1796,9 +1786,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
cstore,
encode_inlined_item,
link_meta,
reachable,
non_inlineable_statics,
codemap,
..
} = parms;
let type_abbrevs = @RefCell::new(HashMap::new());
@ -1814,8 +1802,6 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
cstore: cstore,
encode_inlined_item: encode_inlined_item,
type_abbrevs: type_abbrevs,
reachable: reachable,
codemap: codemap,
};
let mut ebml_w = writer::Encoder(wr);

View file

@ -2552,8 +2552,6 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::EncodeI
link_meta: link_meta,
cstore: cx.sess.cstore,
encode_inlined_item: ie,
reachable: cx.reachable,
codemap: cx.sess.codemap,
}
}

View file

@ -9,6 +9,7 @@
// except according to those terms.
use std::cell::RefCell;
use std::io;
use std::io::Process;
use std::local_data;
use std::os;
@ -128,7 +129,10 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool)
let exe = outdir.path().join("rust_out");
let out = Process::output(exe.as_str().unwrap(), []);
match out {
Err(e) => fail!("couldn't run the test: {}", e),
Err(e) => fail!("couldn't run the test: {}{}", e,
if e.kind == io::PermissionDenied {
" - maybe your tempdir is mounted with noexec?"
} else { "" }),
Ok(out) => {
if should_fail && out.status.success() {
fail!("test executable succeeded when it should have failed");

View file

@ -58,22 +58,6 @@ use rt::task::{Task, BlockedTask};
use super::Port;
use uint;
macro_rules! select {
(
$($name:pat = $port:ident.$meth:ident() => $code:expr),+
) => ({
use std::comm::Select;
let sel = Select::new();
$( let mut $port = sel.handle(&$port); )+
unsafe {
$( $port.add(); )+
}
let ret = sel.wait();
$( if ret == $port.id() { let $name = $port.$meth(); $code } else )+
{ unreachable!() }
})
}
/// The "port set" of the select interface. This structure is used to manage a
/// set of ports which are being selected over.
pub struct Select {

View file

@ -580,7 +580,7 @@ pub trait Unsigned { fn fmt(&self, &mut Formatter) -> Result; }
/// Format trait for the `o` character
#[allow(missing_doc)]
pub trait Octal { fn fmt(&self, &mut Formatter) -> Result; }
/// Format trait for the `b` character
/// Format trait for the `t` character
#[allow(missing_doc)]
pub trait Binary { fn fmt(&self, &mut Formatter) -> Result; }
/// Format trait for the `x` character

View file

@ -368,3 +368,47 @@ macro_rules! vec(
})
)
/// A macro to select an event from a number of ports.
///
/// This macro is used to wait for the first event to occur on a number of
/// ports. It places no restrictions on the types of ports given to this macro,
/// this can be viewed as a heterogeneous select.
///
/// # Example
///
/// ```
/// let (p1, c1) = Chan::new();
/// let (p2, c2) = Chan::new();
/// # fn long_running_task() {}
/// # fn calculate_the_answer() -> int { 42 }
///
/// spawn(proc() { long_running_task(); c1.send(()) });
/// spawn(proc() { c2.send(calculate_the_answer()) });
///
/// select! (
/// () = p1.recv() => println!("the long running task finished first"),
/// answer = p2.recv() => {
/// println!("the answer was: {}", answer);
/// }
/// )
/// ```
///
/// For more information about select, see the `std::comm::Select` structure.
#[macro_export]
#[experimental]
macro_rules! select {
(
$($name:pat = $port:ident.$meth:ident() => $code:expr),+
) => ({
use std::comm::Select;
let sel = Select::new();
$( let mut $port = sel.handle(&$port); )+
unsafe {
$( $port.add(); )+
}
let ret = sel.wait();
$( if ret == $port.id() { let $name = $port.$meth(); $code } else )+
{ unreachable!() }
})
}

View file

@ -865,12 +865,44 @@ pub fn prefix(path: &Path) -> Option<PathPrefix> {
path.prefix
}
/// Returns whether the Path's prefix is a verbatim prefix, i.e. \\?\
/// Returns whether the Path's prefix is a verbatim prefix, i.e. `\\?\`
#[inline]
pub fn is_verbatim(path: &Path) -> bool {
prefix_is_verbatim(path.prefix)
}
/// Returns the non-verbatim equivalent of the input path, if possible.
/// If the input path is a device namespace path, None is returned.
/// If the input path is not verbatim, it is returned as-is.
/// If the input path is verbatim, but the same path can be expressed as
/// non-verbatim, the non-verbatim version is returned.
/// Otherwise, None is returned.
pub fn make_non_verbatim(path: &Path) -> Option<Path> {
let new_path = match path.prefix {
Some(VerbatimPrefix(_)) | Some(DeviceNSPrefix(_)) => return None,
Some(UNCPrefix(_,_)) | Some(DiskPrefix) | None => return Some(path.clone()),
Some(VerbatimDiskPrefix) => {
// \\?\D:\
Path::new(path.repr.slice_from(4))
}
Some(VerbatimUNCPrefix(_,_)) => {
// \\?\UNC\server\share
Path::new(format!(r"\\{}", path.repr.slice_from(7)))
}
};
if new_path.prefix.is_none() {
// \\?\UNC\server is a VerbatimUNCPrefix
// but \\server is nothing
return None;
}
// now ensure normalization didn't change anything
if path.repr.slice_from(path.prefix_len()) == new_path.repr.slice_from(new_path.prefix_len()) {
Some(new_path)
} else {
None
}
}
/// The standard path separator character
pub static SEP: char = '\\';
/// The standard path separator byte
@ -926,7 +958,6 @@ pub enum PathPrefix {
DiskPrefix
}
// FIXME (#8169): Make private once visibility is fixed
fn parse_prefix<'a>(mut path: &'a str) -> Option<PathPrefix> {
if path.starts_with("\\\\") {
// \\
@ -2285,4 +2316,38 @@ mod tests {
t!(s: ".", [b!(".")]);
// since this is really a wrapper around str_components, those tests suffice
}
#[test]
fn test_make_non_verbatim() {
macro_rules! t(
($path:expr, $exp:expr) => (
{
let path = Path::new($path);
let exp: Option<&str> = $exp;
let exp = exp.map(|s| Path::new(s));
assert_eq!(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"));
t!(r"C:\a\b\c", Some(r"C:\a\b\c"));
t!(r"C:a\b\c", Some(r"C:a\b\c"));
t!(r"\\server\share\foo", Some(r"\\server\share\foo"));
t!(r"\\.\foo", None);
t!(r"\\?\foo", None);
t!(r"\\?\C:", None);
t!(r"\\?\C:foo", None);
t!(r"\\?\C:\", Some(r"C:\"));
t!(r"\\?\C:\foo", Some(r"C:\foo"));
t!(r"\\?\C:\foo\bar\baz", Some(r"C:\foo\bar\baz"));
t!(r"\\?\C:\foo\.\bar\baz", None);
t!(r"\\?\C:\foo\bar\..\baz", None);
t!(r"\\?\C:\foo\bar\..", None);
t!(r"\\?\UNC\server\share\foo", Some(r"\\server\share\foo"));
t!(r"\\?\UNC\server\share", Some(r"\\server\share"));
t!(r"\\?\UNC\server", None);
t!(r"\\?\UNC\server\", None);
}
}

View file

@ -420,10 +420,10 @@ impl CodeMap {
fn lookup_pos(&self, pos: BytePos) -> Loc {
let FileMapAndLine {fm: f, line: a} = self.lookup_line(pos);
let line = a + 1u; // Line numbers start at 1
let chpos = self.bytepos_to_charpos(pos);
let chpos = self.bytepos_to_file_charpos(pos);
let lines = f.lines.borrow();
let linebpos = lines.get()[a];
let linechpos = self.bytepos_to_charpos(linebpos);
let linechpos = self.bytepos_to_file_charpos(linebpos);
debug!("codemap: byte pos {:?} is on the line at byte pos {:?}",
pos, linebpos);
debug!("codemap: char pos {:?} is on the line at char pos {:?}",
@ -446,8 +446,8 @@ impl CodeMap {
return FileMapAndBytePos {fm: fm, pos: offset};
}
// Converts an absolute BytePos to a CharPos relative to the codemap.
fn bytepos_to_charpos(&self, bpos: BytePos) -> CharPos {
// Converts an absolute BytePos to a CharPos relative to the filemap.
fn bytepos_to_file_charpos(&self, bpos: BytePos) -> CharPos {
debug!("codemap: converting {:?} to char pos", bpos);
let idx = self.lookup_filemap_idx(bpos);
let files = self.files.borrow();
@ -471,7 +471,8 @@ impl CodeMap {
}
}
CharPos(bpos.to_uint() - total_extra_bytes)
assert!(map.start_pos.to_uint() + total_extra_bytes <= bpos.to_uint());
CharPos(bpos.to_uint() - map.start_pos.to_uint() - total_extra_bytes)
}
}
@ -501,7 +502,7 @@ mod test {
fm.next_line(BytePos(2));
}
fn init_code_map() ->CodeMap {
fn init_code_map() -> CodeMap {
let cm = CodeMap::new();
let fm1 = cm.new_filemap(~"blork.rs",~"first line.\nsecond line");
let fm2 = cm.new_filemap(~"empty.rs",~"");
@ -532,14 +533,14 @@ mod test {
#[test]
fn t4() {
// Test bytepos_to_charpos
// Test bytepos_to_file_charpos
let cm = init_code_map();
let cp1 = cm.bytepos_to_charpos(BytePos(22));
let cp1 = cm.bytepos_to_file_charpos(BytePos(22));
assert_eq!(cp1, CharPos(22));
let cp2 = cm.bytepos_to_charpos(BytePos(23));
assert_eq!(cp2, CharPos(23));
let cp2 = cm.bytepos_to_file_charpos(BytePos(23));
assert_eq!(cp2, CharPos(0));
}
#[test]
@ -557,4 +558,45 @@ mod test {
assert_eq!(loc2.line, 1);
assert_eq!(loc2.col, CharPos(0));
}
fn init_code_map_mbc() -> CodeMap {
let cm = CodeMap::new();
// € is a three byte utf8 char.
let fm1 = cm.new_filemap(~"blork.rs",~"fir€st €€€€ line.\nsecond line");
let fm2 = cm.new_filemap(~"blork2.rs",~"first line€€.\n€ second line");
fm1.next_line(BytePos(0));
fm1.next_line(BytePos(22));
fm2.next_line(BytePos(39));
fm2.next_line(BytePos(57));
fm1.record_multibyte_char(BytePos(3), 3);
fm1.record_multibyte_char(BytePos(9), 3);
fm1.record_multibyte_char(BytePos(12), 3);
fm1.record_multibyte_char(BytePos(15), 3);
fm1.record_multibyte_char(BytePos(18), 3);
fm2.record_multibyte_char(BytePos(49), 3);
fm2.record_multibyte_char(BytePos(52), 3);
fm2.record_multibyte_char(BytePos(57), 3);
cm
}
#[test]
fn t6() {
// Test bytepos_to_file_charpos in the presence of multi-byte chars
let cm = init_code_map_mbc();
let cp1 = cm.bytepos_to_file_charpos(BytePos(3));
assert_eq!(cp1, CharPos(3));
let cp2 = cm.bytepos_to_file_charpos(BytePos(6));
assert_eq!(cp2, CharPos(4));
let cp3 = cm.bytepos_to_file_charpos(BytePos(55));
assert_eq!(cp3, CharPos(12));
let cp4 = cm.bytepos_to_file_charpos(BytePos(60));
assert_eq!(cp4, CharPos(15));
}
}

View file

@ -9,7 +9,7 @@
// except according to those terms.
/*!
The compiler code necessary for #[deriving(Decodable)]. See
The compiler code necessary for `#[deriving(Decodable)]`. See
encodable.rs for more.
*/

View file

@ -10,20 +10,20 @@
/*!
The compiler code necessary to implement the #[deriving(Encodable)]
(and Decodable, in decodable.rs) extension. The idea here is that
type-defining items may be tagged with #[deriving(Encodable,
Decodable)].
The compiler code necessary to implement the `#[deriving(Encodable)]`
(and `Decodable`, in decodable.rs) extension. The idea here is that
type-defining items may be tagged with `#[deriving(Encodable, Decodable)]`.
For example, a type like:
```ignore
#[deriving(Encodable, Decodable)]
struct Node {id: uint}
#[deriving(Encodable, Decodable)]
struct Node { id: uint }
```
would generate two implementations like:
```ignore
impl<S:serialize::Encoder> Encodable<S> for Node {
fn encode(&self, s: &S) {
s.emit_struct("Node", 1, || {
@ -41,13 +41,14 @@ impl<D:Decoder> Decodable for node_id {
})
}
}
```
Other interesting scenarios are whe the item has type parameters or
references other non-built-in types. A type definition like:
```ignore
#[deriving(Encodable, Decodable)]
struct spanned<T> {node: T, span: Span}
#[deriving(Encodable, Decodable)]
struct spanned<T> { node: T, span: Span }
```
would yield functions like:

View file

@ -16,6 +16,7 @@ access to the fields of the 4 different sorts of structs and enum
variants, as well as creating the method and impl ast instances.
Supported features (fairly exhaustive):
- Methods taking any number of parameters of any type, and returning
any type, other than vectors, bottom and closures.
- Generating `impl`s for types with type parameters and lifetimes
@ -59,7 +60,7 @@ associated with. It is only not `None` when the associated field has
an identifier in the source code. For example, the `x`s in the
following snippet
~~~notrust
```rust
struct A { x : int }
struct B(int);
@ -68,7 +69,7 @@ enum C {
C0(int),
C1 { x: int }
}
~~~
```
The `int`s in `B` and `C0` don't have an identifier, so the
`Option<ident>`s would be `None` for them.
@ -83,7 +84,7 @@ variants, it is represented as a count of 0.
The following simplified `Eq` is used for in-code examples:
~~~notrust
```rust
trait Eq {
fn eq(&self, other: &Self);
}
@ -92,7 +93,7 @@ impl Eq for int {
*self == *other
}
}
~~~
```
Some examples of the values of `SubstructureFields` follow, using the
above `Eq`, `A`, `B` and `C`.

View file

@ -9,10 +9,10 @@
// except according to those terms.
/*!
The compiler code necessary to implement the #[deriving] extensions.
The compiler code necessary to implement the `#[deriving]` extensions.
FIXME (#2810)--Hygiene. Search for "__" strings (in other files too).
FIXME (#2810): hygiene. Search for "__" strings (in other files too).
We also assume "extra" is the standard library, and "std" is the core
library.

View file

@ -0,0 +1,6 @@
-include ../tools.mk
all: $(call STATICLIB,foo)
$(RUSTC) foo.rs
$(RUSTC) bar.rs
$(call RUN,bar)

View file

@ -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.
extern crate foo;
#[link(name = "foo")]
extern {}
fn main() {
foo::foo();
}

View file

@ -0,0 +1 @@
void some_c_symbol() {}

View file

@ -0,0 +1,19 @@
// 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 = "rlib"];
extern {
fn some_c_symbol();
}
pub fn foo() {
unsafe { some_c_symbol() }
}