diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 5de7e6957c6f1..84b8ad333c17a 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -10,6 +10,7 @@ import argparse import contextlib +import hashlib import os import shutil import subprocess @@ -18,13 +19,29 @@ def get(url, path, verbose=False): print("downloading " + url) - # see http://serverfault.com/questions/301128/how-to-download - if sys.platform == 'win32': - run(["PowerShell.exe", "/nologo", "-Command", - "(New-Object System.Net.WebClient).DownloadFile('" + url + - "', '" + path + "')"], verbose=verbose) - else: - run(["curl", "-o", path, url], verbose=verbose) + sha_url = url + ".sha256" + sha_path = path + ".sha256" + for _url, _path in ((url, path), (sha_url, sha_path)): + # see http://serverfault.com/questions/301128/how-to-download + if sys.platform == 'win32': + run(["PowerShell.exe", "/nologo", "-Command", + "(New-Object System.Net.WebClient)" + ".DownloadFile('{}', '{}')".format(_url, _path)], + verbose=verbose) + else: + run(["curl", "-o", _path, _url], verbose=verbose) + print("verifying " + path) + with open(path, "rb") as f: + found = hashlib.sha256(f.read()).hexdigest() + with open(sha_path, "r") as f: + expected, _ = f.readline().split() + if found != expected: + err = ("invalid checksum:\n" + " found: {}\n" + " expected: {}".format(found, expected)) + if verbose: + raise RuntimeError(err) + sys.exit(err) def unpack(tarball, dst, verbose=False, match=None): print("extracting " + tarball) @@ -57,9 +74,10 @@ def run(args, verbose=False): ret = subprocess.Popen(args) code = ret.wait() if code != 0: - if not verbose: - print("failed to run: " + ' '.join(args)) - raise RuntimeError("failed to run command") + err = "failed to run: " + ' '.join(args) + if verbose: + raise RuntimeError(err) + sys.exit(err) class RustBuild: def download_rust_nightly(self): @@ -210,7 +228,10 @@ def build_triple(self): if sys.platform == 'win32': return 'x86_64-pc-windows-msvc' else: - raise + err = "uname not found" + if self.verbose: + raise Exception(err) + sys.exit(err) # Darwin's `uname -s` lies and always returns i386. We have to use # sysctl instead. @@ -253,7 +274,10 @@ def build_triple(self): cputype = 'x86_64' ostype = 'pc-windows-gnu' else: - raise ValueError("unknown OS type: " + ostype) + err = "unknown OS type: " + ostype + if self.verbose: + raise ValueError(err) + sys.exit(err) if cputype in {'i386', 'i486', 'i686', 'i786', 'x86'}: cputype = 'i686' @@ -269,7 +293,10 @@ def build_triple(self): elif cputype in {'amd64', 'x86_64', 'x86-64', 'x64'}: cputype = 'x86_64' else: - raise ValueError("unknown cpu type: " + cputype) + err = "unknown cpu type: " + cputype + if self.verbose: + raise ValueError(err) + sys.exit(err) return cputype + '-' + ostype diff --git a/src/doc/book/closures.md b/src/doc/book/closures.md index a8135ad384932..d81619b647fd0 100644 --- a/src/doc/book/closures.md +++ b/src/doc/book/closures.md @@ -492,12 +492,12 @@ fn factory() -> Box i32> { Box::new(move |x| x + num) } -# fn main() { +fn main() { let f = factory(); let answer = f(1); assert_eq!(6, answer); -# } +} ``` By making the inner closure a `move Fn`, we create a new stack frame for our diff --git a/src/doc/book/getting-started.md b/src/doc/book/getting-started.md index 16141d936ebcc..1fe3f6da0ebc7 100644 --- a/src/doc/book/getting-started.md +++ b/src/doc/book/getting-started.md @@ -575,8 +575,12 @@ look something like this: name = "hello_world" version = "0.1.0" authors = ["Your Name "] + +[dependencies] ``` +Do not worry about the `[dependencies]` line, we will come back to it later. + Cargo has populated *Cargo.toml* with reasonable defaults based on the arguments you gave it and your `git` global configuration. You may notice that Cargo has also initialized the `hello_world` directory as a `git` repository. diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 6a62e00d31169..ca4c9bfd9544c 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -96,8 +96,10 @@ mod imp { libc::realloc(ptr as *mut libc::c_void, size as libc::size_t) as *mut u8 } else { let new_ptr = allocate(size, align); - ptr::copy(ptr, new_ptr, cmp::min(size, old_size)); - deallocate(ptr, old_size, align); + if !new_ptr.is_null() { + ptr::copy(ptr, new_ptr, cmp::min(size, old_size)); + deallocate(ptr, old_size, align); + } new_ptr } } diff --git a/src/librustc/diagnostics.rs b/src/librustc/diagnostics.rs index 0b1c9609a0f0d..34b98a3467780 100644 --- a/src/librustc/diagnostics.rs +++ b/src/librustc/diagnostics.rs @@ -292,7 +292,7 @@ E0072: r##" When defining a recursive struct or enum, any use of the type being defined from inside the definition must occur behind a pointer (like `Box` or `&`). This is because structs and enums must have a well-defined size, and without -the pointer the size of the type would need to be unbounded. +the pointer, the size of the type would need to be unbounded. Consider the following erroneous definition of a type for a list of bytes: diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 86531ced8dfae..83929c17ca3e4 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -189,13 +189,19 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> { match self.items.items[item_index] { Some(original_def_id) if original_def_id != item_def_id => { let cstore = &self.session.cstore; - let span = self.ast_map.span_if_local(item_def_id) - .expect("we should have found local duplicate earlier"); - let mut err = struct_span_err!(self.session, - span, - E0152, - "duplicate lang item found: `{}`.", - LanguageItems::item_name(item_index)); + let name = LanguageItems::item_name(item_index); + let mut err = match self.ast_map.span_if_local(item_def_id) { + Some(span) => struct_span_err!( + self.session, + span, + E0152, + "duplicate lang item found: `{}`.", + name), + None => self.session.struct_err(&format!( + "duplicate lang item in crate `{}`: `{}`.", + cstore.crate_name(item_def_id.krate), + name)), + }; if let Some(span) = self.ast_map.span_if_local(original_def_id) { span_note!(&mut err, span, "first defined here."); diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs index 7675e1de95827..8c22ddbb462c0 100644 --- a/src/librustc_trans/callee.rs +++ b/src/librustc_trans/callee.rs @@ -582,15 +582,19 @@ fn get_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("get_fn: not casting pointer!"); attributes::from_fn_attrs(ccx, attrs, llfn); - if let Some(id) = local_item { + if local_item.is_some() { // FIXME(eddyb) Doubt all extern fn should allow unwinding. attributes::unwind(llfn, true); - ccx.item_symbols().borrow_mut().insert(id, sym); } llfn }; + // Always insert into item_symbols, in case this item is exported. + if let Some(id) = local_item { + ccx.item_symbols().borrow_mut().insert(id, sym); + } + ccx.instances().borrow_mut().insert(instance, llfn); immediate_rvalue(llfn, fn_ptr_ty) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c5850089578cd..ba1fbc75c18a3 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2489,7 +2489,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi } fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item, - link: AssocItemLink, render_static: bool, + link: AssocItemLink, render_static: bool, is_default_item: bool, outer_version: Option<&str>) -> fmt::Result { let shortty = shortty(item); let name = item.name.as_ref().unwrap(); @@ -2540,17 +2540,16 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi _ => panic!("can't make docs for trait item with name {:?}", item.name) } - match link { - AssocItemLink::Anchor if !is_static || render_static => { - document(w, cx, item) - }, - _ => Ok(()), + if !is_default_item && (!is_static || render_static) { + document(w, cx, item) + } else { + Ok(()) } } write!(w, "
")?; for trait_item in &i.impl_.items { - doctraititem(w, cx, trait_item, link, render_header, outer_version)?; + doctraititem(w, cx, trait_item, link, render_header, false, outer_version)?; } fn render_default_items(w: &mut fmt::Formatter, @@ -2567,7 +2566,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi let did = i.trait_.as_ref().unwrap().def_id().unwrap(); let assoc_link = AssocItemLink::GotoSource(did, &i.provided_trait_methods); - doctraititem(w, cx, trait_item, assoc_link, render_static, + doctraititem(w, cx, trait_item, assoc_link, render_static, true, outer_version)?; } Ok(()) diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 8550617560df3..cd7b0fcfb0044 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -504,6 +504,13 @@ pub fn expand_item_mac(it: P, /// Expand a stmt fn expand_stmt(stmt: Stmt, fld: &mut MacroExpander) -> SmallVector { + // perform all pending renames + let stmt = { + let pending_renames = &mut fld.cx.syntax_env.info().pending_renames; + let mut rename_fld = IdentRenamer{renames:pending_renames}; + rename_fld.fold_stmt(stmt).expect_one("rename_fold didn't return one value") + }; + let (mac, style, attrs) = match stmt.node { StmtKind::Mac(mac, style, attrs) => (mac, style, attrs), _ => return expand_non_macro_stmt(stmt, fld) @@ -717,14 +724,8 @@ pub fn expand_block(blk: P, fld: &mut MacroExpander) -> P { pub fn expand_block_elts(b: P, fld: &mut MacroExpander) -> P { b.map(|Block {id, stmts, expr, rules, span}| { let new_stmts = stmts.into_iter().flat_map(|x| { - // perform all pending renames - let renamed_stmt = { - let pending_renames = &mut fld.cx.syntax_env.info().pending_renames; - let mut rename_fld = IdentRenamer{renames:pending_renames}; - rename_fld.fold_stmt(x).expect_one("rename_fold didn't return one value") - }; - // expand macros in the statement - fld.fold_stmt(renamed_stmt).into_iter() + // perform pending renames and expand macros in the statement + fld.fold_stmt(x).into_iter() }).collect(); let new_expr = expr.map(|x| { let expr = { diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 77bae4cb3f6c4..87ab3dad50c70 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -1014,6 +1014,7 @@ fn is_in_follow(_: &ExtCtxt, tok: &Token, frag: &str) -> Result { match *tok { OpenDelim(token::DelimToken::Brace) | OpenDelim(token::DelimToken::Bracket) | Comma | FatArrow | Colon | Eq | Gt | Semi | BinOp(token::Or) => Ok(true), + MatchNt(_, ref frag, _, _) if frag.name.as_str() == "block" => Ok(true), Ident(i, _) if (i.name.as_str() == "as" || i.name.as_str() == "where") => Ok(true), _ => Ok(false) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index fc18ef407ab2f..24a62a3dc2a85 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -45,8 +45,8 @@ use std::cmp; // The version numbers here correspond to the version in which the current status // was set. This is most important for knowing when a particular feature became // stable (active). -// NB: The featureck.py script parses this information directly out of the source -// so take care when modifying it. +// NB: The tidy tool parses this information directly out of the source so take +// care when modifying it. const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option, Status)] = &[ ("globs", "1.0.0", None, Accepted), ("macro_rules", "1.0.0", None, Accepted), diff --git a/src/test/auxiliary/foreign_lib.rs b/src/test/auxiliary/foreign_lib.rs index 92239ce55981c..460d0a0088ce2 100644 --- a/src/test/auxiliary/foreign_lib.rs +++ b/src/test/auxiliary/foreign_lib.rs @@ -9,6 +9,7 @@ // except according to those terms. #![crate_name="foreign_lib"] + #![feature(libc)] pub mod rustrt { @@ -19,3 +20,29 @@ pub mod rustrt { pub fn rust_get_test_int() -> libc::intptr_t; } } + +pub mod rustrt2 { + extern crate libc; + + extern { + pub fn rust_get_test_int() -> libc::intptr_t; + } +} + +pub mod rustrt3 { + // Different type, but same ABI (on all supported platforms). + // Ensures that we don't ICE or trigger LLVM asserts when + // importing the same symbol under different types. + // See https://github.com/rust-lang/rust/issues/32740. + extern { + pub fn rust_get_test_int() -> *const u8; + } +} + +pub fn local_uses() { + unsafe { + let x = rustrt::rust_get_test_int(); + assert_eq!(x, rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + } +} diff --git a/src/test/compile-fail/issue-32922.rs b/src/test/compile-fail/issue-32922.rs new file mode 100644 index 0000000000000..491c087c101de --- /dev/null +++ b/src/test/compile-fail/issue-32922.rs @@ -0,0 +1,41 @@ +// Copyright 2016 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. + +#![feature(rustc_attrs)] +#![allow(warnings)] + +macro_rules! foo { () => { + let x = 1; + macro_rules! bar { () => {x} } + let _ = bar!(); +}} + +macro_rules! bar { // test issue #31856 + ($n:ident) => ( + let a = 1; + let $n = a; + ) +} + +macro_rules! baz { + ($i:ident) => { + let mut $i = 2; + $i = $i + 1; + } +} + +#[rustc_error] +fn main() { //~ ERROR compilation successful + foo! {}; + bar! {}; + + let mut a = true; + baz!(a); +} diff --git a/src/test/compile-fail/macro-follow.rs b/src/test/compile-fail/macro-follow.rs index 35944bada4d64..f985340c52410 100644 --- a/src/test/compile-fail/macro-follow.rs +++ b/src/test/compile-fail/macro-follow.rs @@ -55,7 +55,7 @@ macro_rules! follow_expr { ($e:expr $m:meta) => {}; //~ERROR `$e:expr` is followed by `$m:meta` } // FOLLOW(ty) = {OpenDelim(Brace), Comma, FatArrow, Colon, Eq, Gt, Semi, Or, -// Ident(as), Ident(where), OpenDelim(Bracket)} +// Ident(as), Ident(where), OpenDelim(Bracket), Nonterminal(Block)} macro_rules! follow_ty { ($t:ty ()) => {}; //~WARN `$t:ty` is followed by `(` ($t:ty []) => {}; // ok (RFC 1462) @@ -67,7 +67,7 @@ macro_rules! follow_ty { ($t:ty $t:ty) => {}; //~ERROR `$t:ty` is followed by `$t:ty` ($t:ty $s:stmt) => {}; //~ERROR `$t:ty` is followed by `$s:stmt` ($t:ty $p:path) => {}; //~ERROR `$t:ty` is followed by `$p:path` - ($t:ty $b:block) => {}; //~ERROR `$t:ty` is followed by `$b:block` + ($t:ty $b:block) => {}; // ok (RFC 1494) ($t:ty $i:ident) => {}; //~ERROR `$t:ty` is followed by `$i:ident` ($t:ty $t:tt) => {}; //~ERROR `$t:ty` is followed by `$t:tt` ($t:ty $i:item) => {}; //~ERROR `$t:ty` is followed by `$i:item` @@ -109,7 +109,7 @@ macro_rules! follow_path { ($p:path $t:ty) => {}; //~ERROR `$p:path` is followed by `$t:ty` ($p:path $s:stmt) => {}; //~ERROR `$p:path` is followed by `$s:stmt` ($p:path $p:path) => {}; //~ERROR `$p:path` is followed by `$p:path` - ($p:path $b:block) => {}; //~ERROR `$p:path` is followed by `$b:block` + ($p:path $b:block) => {}; // ok (RFC 1494) ($p:path $i:ident) => {}; //~ERROR `$p:path` is followed by `$i:ident` ($p:path $t:tt) => {}; //~ERROR `$p:path` is followed by `$t:tt` ($p:path $i:item) => {}; //~ERROR `$p:path` is followed by `$i:item` diff --git a/src/test/run-pass/foreign-dupe.rs b/src/test/run-pass/foreign-dupe.rs index 4e06c434ccc12..fb162d8793356 100644 --- a/src/test/run-pass/foreign-dupe.rs +++ b/src/test/run-pass/foreign-dupe.rs @@ -8,41 +8,18 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// calling pin_thread and that's having weird side-effects. +// aux-build:foreign_lib.rs -#![feature(libc)] +// Check that we can still call duplicated extern (imported) functions +// which were declared in another crate. See issues #32740 and #32783. -mod rustrt1 { - extern crate libc; - #[link(name = "rust_test_helpers")] - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -mod rustrt2 { - extern crate libc; - - extern { - pub fn rust_get_test_int() -> libc::intptr_t; - } -} - -mod rustrt3 { - // Different type, but same ABI (on all supported platforms). - // Ensures that we don't ICE or trigger LLVM asserts when - // importing the same symbol under different types. - // See https://github.com/rust-lang/rust/issues/32740. - extern { - pub fn rust_get_test_int() -> *const u8; - } -} +extern crate foreign_lib; pub fn main() { unsafe { - let x = rustrt1::rust_get_test_int(); - assert_eq!(x, rustrt2::rust_get_test_int()); - assert_eq!(x as *const _, rustrt3::rust_get_test_int()); + let x = foreign_lib::rustrt::rust_get_test_int(); + assert_eq!(x, foreign_lib::rustrt2::rust_get_test_int()); + assert_eq!(x as *const _, foreign_lib::rustrt3::rust_get_test_int()); } } diff --git a/src/test/run-pass/macro-follow.rs b/src/test/run-pass/macro-follow.rs index ce6498f67f9ee..dca676f8cf95f 100644 --- a/src/test/run-pass/macro-follow.rs +++ b/src/test/run-pass/macro-follow.rs @@ -26,7 +26,7 @@ macro_rules! follow_expr { ($e:expr ;) => {}; } // FOLLOW(ty) = {OpenDelim(Brace), Comma, FatArrow, Colon, Eq, Gt, Semi, Or, -// Ident(as), Ident(where), OpenDelim(Bracket)} +// Ident(as), Ident(where), OpenDelim(Bracket), Nonterminal(Block)} macro_rules! follow_ty { ($t:ty {}) => {}; ($t:ty ,) => {}; @@ -39,6 +39,7 @@ macro_rules! follow_ty { ($t:ty as) => {}; ($t:ty where) => {}; ($t:ty []) => {}; + ($t:ty $b:block) => {}; } // FOLLOW(stmt) = FOLLOW(expr) macro_rules! follow_stmt { @@ -59,6 +60,7 @@ macro_rules! follow_path { ($p:path as) => {}; ($p:path where) => {}; ($p:path []) => {}; + ($p:path $b:block) => {}; } // FOLLOW(block) = any token macro_rules! follow_block { diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs new file mode 100644 index 0000000000000..5eccf97bb5f6f --- /dev/null +++ b/src/test/rustdoc/manual_impl.rs @@ -0,0 +1,78 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// @has manual_impl/trait.T.html +// @has - '//*[@class="docblock"]' 'Docs associated with the trait definition.' +// @has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.' +// @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.' +/// Docs associated with the trait definition. +pub trait T { + /// Docs associated with the trait a_method definition. + fn a_method(&self) -> usize; + + /// Docs associated with the trait b_method definition. + fn b_method(&self) -> usize { + self.a_method() + } +} + +// @has manual_impl/struct.S1.html '//*[@class="trait"]' 'T' +// @has - '//*[@class="docblock"]' 'Docs associated with the S1 trait implementation.' +// @has - '//*[@class="docblock"]' 'Docs associated with the S1 trait a_method implementation.' +// @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.' +// @!has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.' +pub struct S1(usize); + +/// Docs associated with the S1 trait implementation. +impl T for S1 { + /// Docs associated with the S1 trait a_method implementation. + fn a_method(&self) -> usize { + self.0 + } +} + +// @has manual_impl/struct.S2.html '//*[@class="trait"]' 'T' +// @has - '//*[@class="docblock"]' 'Docs associated with the S2 trait implementation.' +// @has - '//*[@class="docblock"]' 'Docs associated with the S2 trait a_method implementation.' +// @has - '//*[@class="docblock"]' 'Docs associated with the S2 trait b_method implementation.' +// @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.' +// @!has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.' +pub struct S2(usize); + +/// Docs associated with the S2 trait implementation. +impl T for S2 { + /// Docs associated with the S2 trait a_method implementation. + fn a_method(&self) -> usize { + self.0 + } + + /// Docs associated with the S2 trait b_method implementation. + fn b_method(&self) -> usize { + 5 + } +} + +// @has manual_impl/struct.S3.html '//*[@class="trait"]' 'T' +// @has - '//*[@class="docblock"]' 'Docs associated with the S3 trait implementation.' +// @has - '//*[@class="docblock"]' 'Docs associated with the S3 trait b_method implementation.' +// @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.' +pub struct S3(usize); + +/// Docs associated with the S3 trait implementation. +impl T for S3 { + fn a_method(&self) -> usize { + self.0 + } + + /// Docs associated with the S3 trait b_method implementation. + fn b_method(&self) -> usize { + 5 + } +}