From 5a8bbf12023db80568cdf6a1d8851a5623a7e42a Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 13 Apr 2016 00:13:44 +0000 Subject: [PATCH 01/17] Fixes #32922, a macro hygiene bug --- src/libsyntax/ext/expand.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) 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 = { From f08f75f25c2177748a1ebd6f22f14874c47939e2 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Wed, 13 Apr 2016 00:15:37 +0000 Subject: [PATCH 02/17] Add regression test --- src/test/compile-fail/issue-32922.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/test/compile-fail/issue-32922.rs diff --git a/src/test/compile-fail/issue-32922.rs b/src/test/compile-fail/issue-32922.rs new file mode 100644 index 0000000000000..fdf5cbfd3c400 --- /dev/null +++ b/src/test/compile-fail/issue-32922.rs @@ -0,0 +1,20 @@ +// 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)] + +macro_rules! foo { () => { + let x = 1; + macro_rules! bar { () => {x} } + let _ = bar!(); +}} + +#[rustc_error] +fn main() { foo! {}; } //~ ERROR compilation successful From 340eff6604c167eec6cd9832ba53308b1c0de7d1 Mon Sep 17 00:00:00 2001 From: Leo Testard Date: Wed, 13 Apr 2016 11:27:30 +0200 Subject: [PATCH 03/17] Update a comment to reflect changes in tidy checks. --- src/libsyntax/feature_gate.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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), From 722faa024b99473eeda2a58b7c8f3e7fb2ad1eab Mon Sep 17 00:00:00 2001 From: Deepak Kannan Date: Wed, 13 Apr 2016 16:01:05 +0530 Subject: [PATCH 04/17] Doc fix: Update Cargo.toml in book/getting-started The Cargo.toml mentioned in book/getting-started is missing the section called `[dependencies]` --- src/doc/book/getting-started.md | 4 ++++ 1 file changed, 4 insertions(+) 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. From 974f1eff58d01ce0bb5583adf0066a84d8eed812 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Thu, 14 Apr 2016 01:20:22 +0000 Subject: [PATCH 05/17] Add test for issue #31856 --- src/test/compile-fail/issue-32922.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/test/compile-fail/issue-32922.rs b/src/test/compile-fail/issue-32922.rs index fdf5cbfd3c400..4206b16a41952 100644 --- a/src/test/compile-fail/issue-32922.rs +++ b/src/test/compile-fail/issue-32922.rs @@ -9,6 +9,7 @@ // except according to those terms. #![feature(rustc_attrs)] +#![allow(warnings)] macro_rules! foo { () => { let x = 1; @@ -16,5 +17,15 @@ macro_rules! foo { () => { let _ = bar!(); }} +macro_rules! bar { // test issue #31856 + ($n:ident) => ( + let a = 1; + let $n = a; + ) +} + #[rustc_error] -fn main() { foo! {}; } //~ ERROR compilation successful +fn main() { //~ ERROR compilation successful + foo! {}; + bar! {}; +} From ffff91a8e8d1b29164db89019429a712feca4a18 Mon Sep 17 00:00:00 2001 From: Nick Platt Date: Wed, 13 Apr 2016 22:10:25 -0400 Subject: [PATCH 06/17] rustbuild: Improve error messaging in bootstrap.py For normal invocations, print a short error message and exit. When the verbose option is enabled, also print the backtrace. --- src/bootstrap/bootstrap.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 5de7e6957c6f1..5c50599fbf4bd 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -57,9 +57,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 +211,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 +257,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 +276,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 From e0f997d3477fe28c2c5d99229bd1cd0de81604b4 Mon Sep 17 00:00:00 2001 From: Nick Platt Date: Wed, 13 Apr 2016 22:10:42 -0400 Subject: [PATCH 07/17] rustbuild: Verify sha256 of downloaded tarballs --- src/bootstrap/bootstrap.py | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 5c50599fbf4bd..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) From 01aebf01bc0cd0d95e02cc4c91059f02e4b03b13 Mon Sep 17 00:00:00 2001 From: Alex Burka Date: Mon, 8 Feb 2016 21:47:57 -0500 Subject: [PATCH 08/17] implement RFC amendment 1494 --- src/libsyntax/ext/tt/macro_rules.rs | 1 + src/test/compile-fail/macro-follow.rs | 6 +++--- src/test/run-pass/macro-follow.rs | 4 +++- 3 files changed, 7 insertions(+), 4 deletions(-) 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/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/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 { From d8d8669439bd9e636b9209733c24c32063cc611d Mon Sep 17 00:00:00 2001 From: pierzchalski Date: Thu, 14 Apr 2016 13:57:01 +1000 Subject: [PATCH 09/17] Delegate whether to print docblocks to 'document' Add test to check this resolves #24838 and #26871. --- src/librustdoc/html/render.rs | 9 ++++----- src/test/rustdoc/manual_impl.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 src/test/rustdoc/manual_impl.rs diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index c5850089578cd..58901dcb38065 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2540,11 +2540,10 @@ 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_static || render_static { + document(w, cx, item) + } else { + Ok(()) } } diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs new file mode 100644 index 0000000000000..540cf58d38ebe --- /dev/null +++ b/src/test/rustdoc/manual_impl.rs @@ -0,0 +1,26 @@ +// 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. + +pub trait T { + fn a_method(&self) -> usize; +} + +// @has manual_impl/struct.S.html '//*[@class="trait"]' 'T' +// @has - '//*[@class="docblock"]' 'Docs associated with the trait implementation.' +// @has - '//*[@class="docblock"]' 'Docs associated with the trait method implementation.' +pub struct S(usize); + +/// Docs associated with the trait implementation. +impl T for S { + /// Docs associated with the trait method implementation. + fn a_method(&self) -> usize { + self.0 + } +} From cd85120ef9be436b8cd32c7208a913cc41c66e13 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 14 Apr 2016 08:39:23 +0300 Subject: [PATCH 10/17] trans: always register an item's symbol, even if duplicated. --- src/librustc_trans/callee.rs | 8 +++++-- src/test/auxiliary/foreign_lib.rs | 27 ++++++++++++++++++++++ src/test/run-pass/foreign-dupe.rs | 37 ++++++------------------------- 3 files changed, 40 insertions(+), 32 deletions(-) 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/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/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()); } } From 571607fe24514b419dea5a596c2d219e2f17dfd1 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 14 Apr 2016 21:24:11 +0200 Subject: [PATCH 11/17] doc: add missing comma --- src/librustc/diagnostics.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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: From 37e59b9239095bf8b0e0d1ae9952707593395956 Mon Sep 17 00:00:00 2001 From: JP Sugarbroad Date: Thu, 14 Apr 2016 13:25:14 -0700 Subject: [PATCH 12/17] Accommodate the case where dup lang items are entirely external. Fixes #32961 --- src/librustc/middle/lang_items.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) 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."); From f91649144e1e2e6b3664545cb7e117d839f9cd95 Mon Sep 17 00:00:00 2001 From: Kaiyin Zhong Date: Fri, 15 Apr 2016 00:51:20 +0200 Subject: [PATCH 13/17] remove "#" symbols to make the code compile --- src/doc/book/closures.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From ca1d29c4debb5a58d9c2a9322eea740ca558ade5 Mon Sep 17 00:00:00 2001 From: Jeffrey Seyfried Date: Fri, 15 Apr 2016 02:22:34 +0000 Subject: [PATCH 14/17] Add another test for issue #31856 --- src/test/compile-fail/issue-32922.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/test/compile-fail/issue-32922.rs b/src/test/compile-fail/issue-32922.rs index 4206b16a41952..491c087c101de 100644 --- a/src/test/compile-fail/issue-32922.rs +++ b/src/test/compile-fail/issue-32922.rs @@ -24,8 +24,18 @@ macro_rules! bar { // test issue #31856 ) } +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); } From d95ca2822cdc67ddec96d16533e23a10d6bfd136 Mon Sep 17 00:00:00 2001 From: pierzchalski Date: Fri, 15 Apr 2016 13:13:55 +1000 Subject: [PATCH 15/17] Add tests against weird provided/required method behaviour In `test/rustdoc/manual_impl.rs` there are now three structs: * S1 implements and documents required method `a_method`. * S2 implements and documents `a_method` as well as provided method `b_method`. * S3 implements `a_method` and `b_method`, but only documents `b_method`. For a struct, we want the rendered trait impls to include documentation if and only if it appears on the trait implementation itself (since users can just go to the trait definition for anything not covered in the impl docs). This means we expect: * S1, S2, and S3 to all include top-level trait impl docs. * S1, S2, and S3 to exclude all trait definition docs. * S1 to show impl docs for `a_method`. * S2 to show impl docs for `a_method` and `b_method`. * S3 to show impl docs for `b_method`. These tests cover those cases. --- src/test/rustdoc/manual_impl.rs | 62 +++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs index 540cf58d38ebe..6675a0fd43b4e 100644 --- a/src/test/rustdoc/manual_impl.rs +++ b/src/test/rustdoc/manual_impl.rs @@ -8,19 +8,67 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +/// 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.S.html '//*[@class="trait"]' 'T' -// @has - '//*[@class="docblock"]' 'Docs associated with the trait implementation.' -// @has - '//*[@class="docblock"]' 'Docs associated with the trait method implementation.' -pub struct S(usize); +// @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 trait implementation. -impl T for S { - /// Docs associated with the trait method implementation. +/// 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 + } } From ec5e0f81cf54ca287e6652923e1bf46f4fc1c783 Mon Sep 17 00:00:00 2001 From: pierzchalski Date: Fri, 15 Apr 2016 14:41:54 +1000 Subject: [PATCH 16/17] Add flag for whether an item is default or not. We don't want to render default item docs but previously `doctraititem` naively delegated to the trait definition in those cases. Updated tests to also check that this doesn't strip default item docs from the trait definition. --- src/librustdoc/html/render.rs | 8 ++++---- src/test/rustdoc/manual_impl.rs | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 58901dcb38065..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,7 +2540,7 @@ 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) } - if !is_static || render_static { + if !is_default_item && (!is_static || render_static) { document(w, cx, item) } else { Ok(()) @@ -2549,7 +2549,7 @@ fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLi 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, @@ -2566,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/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs index 6675a0fd43b4e..5eccf97bb5f6f 100644 --- a/src/test/rustdoc/manual_impl.rs +++ b/src/test/rustdoc/manual_impl.rs @@ -8,6 +8,10 @@ // 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. From 99c05478542c6624d537f587ce34f84d09fd0627 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 15 Apr 2016 10:02:21 -0700 Subject: [PATCH 17/17] alloc_system: Handle failure properly The Unix implementation was incorrectly handling failure for reallocation of over-aligned types by not checking for NULL. Closes #32993 --- src/liballoc_system/lib.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) 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 } }