diff --git a/mk/dist.mk b/mk/dist.mk index 1a4d7a27843..17afeaae377 100644 --- a/mk/dist.mk +++ b/mk/dist.mk @@ -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 diff --git a/src/doc/tutorial.md b/src/doc/tutorial.md index 670ad5800c6..339e5552d7f 100644 --- a/src/doc/tutorial.md +++ b/src/doc/tutorial.md @@ -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 { Cons(T, ~List), @@ -1336,10 +1343,14 @@ impl Eq for List { 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 diff --git a/src/etc/ctags.rust b/src/etc/ctags.rust index f0fab3347d1..b42edf7579a 100644 --- a/src/etc/ctags.rust +++ b/src/etc/ctags.rust @@ -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/ diff --git a/src/etc/pkg/Distribution.xml b/src/etc/pkg/Distribution.xml new file mode 100644 index 00000000000..9c2e5d65884 --- /dev/null +++ b/src/etc/pkg/Distribution.xml @@ -0,0 +1,22 @@ + + + Rust + + + + + + + + + + + + + + + + + + rust.pkg + diff --git a/src/etc/vim/ftplugin/rust.vim b/src/etc/vim/ftplugin/rust.vim index 281a63ef40a..b70cda9b998 100644 --- a/src/etc/vim/ftplugin/rust.vim +++ b/src/etc/vim/ftplugin/rust.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: Rust " Maintainer: Chris Morgan -" 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 [[ :call Rust_Jump('n', 'Back') +nnoremap ]] :call Rust_Jump('n', 'Forward') +xnoremap [[ :call Rust_Jump('v', 'Back') +xnoremap ]] :call Rust_Jump('v', 'Forward') +onoremap [[ :call Rust_Jump('o', 'Back') +onoremap ]] :call Rust_Jump('o', 'Forward') + +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 [[ + \|nunmap ]] + \|xunmap [[ + \|xunmap ]] + \|ounmap [[ + \|ounmap ]] + \" + +if exists('*Rust_Jump') | finish | endif + +function! 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 Rust_Jump_" . a:function . "()" + let cnt = cnt - 1 + endwhile + let &foldenable = foldenable +endfunction + +function! Rust_Jump_Back() + call search('{', 'b') + keepjumps normal! w99[{ +endfunction + +function! Rust_Jump_Forward() + normal! j0 + call search('{', 'b') + keepjumps normal! w99[{% + call search('{') +endfunction diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 837a87879b0..cc158bb44af 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -3,7 +3,7 @@ " Maintainer: Patrick Walton " Maintainer: Ben Blum " Maintainer: Chris Morgan -" 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 "\ { link_meta: &'a LinkMeta, cstore: @cstore::CStore, encode_inlined_item: EncodeInlinedItem<'a>, - reachable: @RefCell>, - 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>, - 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); diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 5df6c231b5c..6a7694b2b81 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -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, } } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index ae22d9c84dc..ab90b27a0de 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -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, 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"); diff --git a/src/libstd/comm/select.rs b/src/libstd/comm/select.rs index 02066086ad7..75e7265705a 100644 --- a/src/libstd/comm/select.rs +++ b/src/libstd/comm/select.rs @@ -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 { diff --git a/src/libstd/fmt/mod.rs b/src/libstd/fmt/mod.rs index 5c0838fadca..bdc1aa75c94 100644 --- a/src/libstd/fmt/mod.rs +++ b/src/libstd/fmt/mod.rs @@ -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 diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 490f2c9b198..e16d944fb46 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -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!() } + }) +} diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 10834aec64c..864cdebe1a0 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -865,12 +865,44 @@ pub fn prefix(path: &Path) -> Option { 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 { + 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 { 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); + } } diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 79ccc8df0f3..7b70e14e802 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -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)); + } } diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs index 623e8ef766c..7aaa66cbfb5 100644 --- a/src/libsyntax/ext/deriving/decodable.rs +++ b/src/libsyntax/ext/deriving/decodable.rs @@ -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. */ diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs index 2bc661ff27a..ae23013b7cc 100644 --- a/src/libsyntax/ext/deriving/encodable.rs +++ b/src/libsyntax/ext/deriving/encodable.rs @@ -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 Encodable for Node { fn encode(&self, s: &S) { s.emit_struct("Node", 1, || { @@ -41,13 +41,14 @@ impl 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 {node: T, span: Span} +#[deriving(Encodable, Decodable)] +struct spanned { node: T, span: Span } ``` would yield functions like: diff --git a/src/libsyntax/ext/deriving/generic.rs b/src/libsyntax/ext/deriving/generic.rs index ded80295320..24d4efb1b0e 100644 --- a/src/libsyntax/ext/deriving/generic.rs +++ b/src/libsyntax/ext/deriving/generic.rs @@ -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`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`. diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs index 9c823449d21..28f039f0818 100644 --- a/src/libsyntax/ext/deriving/mod.rs +++ b/src/libsyntax/ext/deriving/mod.rs @@ -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. diff --git a/src/test/run-make/issue-12446/Makefile b/src/test/run-make/issue-12446/Makefile new file mode 100644 index 00000000000..e864ee0058c --- /dev/null +++ b/src/test/run-make/issue-12446/Makefile @@ -0,0 +1,6 @@ +-include ../tools.mk + +all: $(call STATICLIB,foo) + $(RUSTC) foo.rs + $(RUSTC) bar.rs + $(call RUN,bar) diff --git a/src/test/run-make/issue-12446/bar.rs b/src/test/run-make/issue-12446/bar.rs new file mode 100644 index 00000000000..cd41058744d --- /dev/null +++ b/src/test/run-make/issue-12446/bar.rs @@ -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 or the MIT license +// , 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(); +} diff --git a/src/test/run-make/issue-12446/foo.c b/src/test/run-make/issue-12446/foo.c new file mode 100644 index 00000000000..a58cd8bb7c9 --- /dev/null +++ b/src/test/run-make/issue-12446/foo.c @@ -0,0 +1 @@ +void some_c_symbol() {} diff --git a/src/test/run-make/issue-12446/foo.rs b/src/test/run-make/issue-12446/foo.rs new file mode 100644 index 00000000000..f16dd5e1d5c --- /dev/null +++ b/src/test/run-make/issue-12446/foo.rs @@ -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 or the MIT license +// , 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() } +}