From a8680deb7f950f48b5807a887944fa73af723507 Mon Sep 17 00:00:00 2001 From: Tshepang Lekhonkhobe Date: Thu, 18 Jun 2015 23:48:51 +0200 Subject: [PATCH 1/6] README: improve description of Rust --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e54473a8b4172..c8f00ba1acd8d 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # The Rust Programming Language -Rust is a systems programming language that is fast, memory safe and -multithreaded, but does not employ a garbage collector or otherwise -impose significant runtime overhead. +Rust is a fast systems programming language that guarantees +memory safety and offers painless concurrency ([no data races]). +It does not employ a garbage collector and has minimal runtime overhead. This repo contains the code for `rustc`, the Rust compiler, as well as standard libraries, tools and documentation for Rust. +[no data races]: http://blog.rust-lang.org/2015/04/10/Fearless-Concurrency.html + ## Quick Start Read ["Installing Rust"] from [The Book]. From 1620acf3ad635fbe9aabc62d8269bd90f0289a1b Mon Sep 17 00:00:00 2001 From: Steve Klabnik Date: Fri, 19 Jun 2015 11:22:37 -0400 Subject: [PATCH 2/6] Fix docs for column/line Fixes #26424 --- src/libstd/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 749974c7afab0..02c35e9526d36 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -331,7 +331,7 @@ pub mod builtin { /// A macro which expands to the line number on which it was invoked. /// - /// The expanded expression has type `usize`, and the returned line is not + /// The expanded expression has type `u32`, and the returned line is not /// the invocation of the `line!()` macro itself, but rather the first macro /// invocation leading up to the invocation of the `line!()` macro. /// @@ -346,7 +346,7 @@ pub mod builtin { /// A macro which expands to the column number on which it was invoked. /// - /// The expanded expression has type `usize`, and the returned column is not + /// The expanded expression has type `u32`, and the returned column is not /// the invocation of the `column!()` macro itself, but rather the first macro /// invocation leading up to the invocation of the `column!()` macro. /// From 4fd04c34cdeb3f741e975337b8e86ab4bc23298e Mon Sep 17 00:00:00 2001 From: Philip Munksgaard Date: Fri, 19 Jun 2015 18:36:54 +0200 Subject: [PATCH 3/6] Add test for #24227 --- src/test/run-pass/issue-24227.rs | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/test/run-pass/issue-24227.rs diff --git a/src/test/run-pass/issue-24227.rs b/src/test/run-pass/issue-24227.rs new file mode 100644 index 0000000000000..34c16bd4003ad --- /dev/null +++ b/src/test/run-pass/issue-24227.rs @@ -0,0 +1,27 @@ +// 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. + +// This resulted in an ICE. Test for future-proofing +// Issue #24227 + +#![allow(unused)] + +struct Foo<'a> { + x: &'a u8 +} + +impl<'a> Foo<'a> { + fn foo() { + let mut tmp: Self; + } + +} + +fn main() {} From e132f0bc8e7ac08cad0f2e2cdd55841d0576cf61 Mon Sep 17 00:00:00 2001 From: Alexis Beingessner Date: Fri, 19 Jun 2015 13:55:01 -0700 Subject: [PATCH 4/6] add note for future type-system adventurers --- src/libcore/ptr.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 31cdb6093c8d9..f2792a525d66b 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -512,6 +512,11 @@ impl PartialOrd for *mut T { #[unstable(feature = "unique", reason = "needs an RFC to flesh out design")] pub struct Unique { pointer: NonZero<*const T>, + // NOTE: this marker has no consequences for variance, but is necessary + // for dropck to understand that we logically own a `T`. + // + // For details, see: + // https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data _marker: PhantomData, } From a6cc4dd308213390a53a53101424ca4ef2e351ab Mon Sep 17 00:00:00 2001 From: Nick Hamann Date: Sat, 20 Jun 2015 01:31:31 -0500 Subject: [PATCH 5/6] Add a regression test for #18058. Fixes #18058. --- src/test/compile-fail/issue-18058.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/test/compile-fail/issue-18058.rs diff --git a/src/test/compile-fail/issue-18058.rs b/src/test/compile-fail/issue-18058.rs new file mode 100644 index 0000000000000..bbb540200b436 --- /dev/null +++ b/src/test/compile-fail/issue-18058.rs @@ -0,0 +1,14 @@ +// 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. + +impl Undefined {} +//~^ ERROR use of undeclared type name `Undefined` + +fn main() {} From 634fced396f180eea18a828bdddec3deded61ab8 Mon Sep 17 00:00:00 2001 From: Michael Sproul Date: Sat, 20 Jun 2015 16:30:01 +1000 Subject: [PATCH 6/6] diagnostics: Resurrect the Compiler Error Index. --- mk/docs.mk | 3 +- src/error-index-generator/main.rs | 4 +- src/librustc_typeck/diagnostics.rs | 8 +- src/libsyntax/diagnostics/metadata.rs | 112 +++++++------------------- src/libsyntax/diagnostics/plugin.rs | 20 ++++- 5 files changed, 54 insertions(+), 93 deletions(-) diff --git a/mk/docs.mk b/mk/docs.mk index 0f3d84cf6317c..617c3ddf8dec1 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -77,8 +77,7 @@ ERR_IDX_GEN = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE) D := $(S)src/doc -# FIXME (#25705) eventually may want to put error-index target back here. -DOC_TARGETS := trpl style +DOC_TARGETS := trpl style error-index COMPILER_DOC_TARGETS := DOC_L10N_TARGETS := diff --git a/src/error-index-generator/main.rs b/src/error-index-generator/main.rs index 33cb7584580de..cbb67014e2760 100644 --- a/src/error-index-generator/main.rs +++ b/src/error-index-generator/main.rs @@ -17,6 +17,7 @@ extern crate serialize as rustc_serialize; use std::collections::BTreeMap; use std::fs::{read_dir, File}; use std::io::{Read, Write}; +use std::env; use std::path::Path; use std::error::Error; @@ -106,7 +107,8 @@ r##" } fn main_with_result() -> Result<(), Box> { - let metadata_dir = get_metadata_dir(); + let build_arch = try!(env::var("CFG_BUILD")); + let metadata_dir = get_metadata_dir(&build_arch); let err_map = try!(load_all_errors(&metadata_dir)); try!(render_error_page(&err_map, Path::new("doc/error-index.html"))); Ok(()) diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index d89174295a892..448a9f2b960dc 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -586,9 +586,11 @@ struct ListNode { This type cannot have a well-defined size, because it needs to be arbitrarily large (since we would be able to nest `ListNode`s to any depth). Specifically, - size of `ListNode` = 1 byte for `head` - + 1 byte for the discriminant of the `Option` - + size of `ListNode` +```plain +size of `ListNode` = 1 byte for `head` + + 1 byte for the discriminant of the `Option` + + size of `ListNode` +``` One way to fix this is by wrapping `ListNode` in a `Box`, like so: diff --git a/src/libsyntax/diagnostics/metadata.rs b/src/libsyntax/diagnostics/metadata.rs index 6cb4f70b8607a..e988b74cb3d1d 100644 --- a/src/libsyntax/diagnostics/metadata.rs +++ b/src/libsyntax/diagnostics/metadata.rs @@ -14,24 +14,18 @@ //! currently always a crate name. use std::collections::BTreeMap; -use std::env; use std::path::PathBuf; -use std::fs::{read_dir, create_dir_all, OpenOptions, File}; -use std::io::{Read, Write}; +use std::fs::{remove_file, create_dir_all, File}; +use std::io::Write; use std::error::Error; -use rustc_serialize::json::{self, as_json}; +use rustc_serialize::json::as_json; use codemap::Span; use ext::base::ExtCtxt; use diagnostics::plugin::{ErrorMap, ErrorInfo}; -pub use self::Uniqueness::*; - // Default metadata directory to use for extended error JSON. -const ERROR_METADATA_DIR_DEFAULT: &'static str = "tmp/extended-errors"; - -// The name of the environment variable that sets the metadata dir. -const ERROR_METADATA_VAR: &'static str = "ERROR_METADATA_DIR"; +const ERROR_METADATA_PREFIX: &'static str = "tmp/extended-errors"; /// JSON encodable/decodable version of `ErrorInfo`. #[derive(PartialEq, RustcDecodable, RustcEncodable)] @@ -61,84 +55,32 @@ impl ErrorLocation { } } -/// Type for describing the uniqueness of a set of error codes, as returned by `check_uniqueness`. -pub enum Uniqueness { - /// All errors in the set checked are unique according to the metadata files checked. - Unique, - /// One or more errors in the set occur in another metadata file. - /// This variant contains the first duplicate error code followed by the name - /// of the metadata file where the duplicate appears. - Duplicate(String, String) -} - -/// Get the directory where metadata files should be stored. -pub fn get_metadata_dir() -> PathBuf { - match env::var(ERROR_METADATA_VAR) { - Ok(v) => From::from(v), - Err(_) => From::from(ERROR_METADATA_DIR_DEFAULT) - } -} - -/// Get the path where error metadata for the set named by `name` should be stored. -fn get_metadata_path(name: &str) -> PathBuf { - get_metadata_dir().join(format!("{}.json", name)) +/// Get the directory where metadata for a given `prefix` should be stored. +/// +/// See `output_metadata`. +pub fn get_metadata_dir(prefix: &str) -> PathBuf { + PathBuf::from(ERROR_METADATA_PREFIX).join(prefix) } -/// Check that the errors in `err_map` aren't present in any metadata files in the -/// metadata directory except the metadata file corresponding to `name`. -pub fn check_uniqueness(name: &str, err_map: &ErrorMap) -> Result> { - let metadata_dir = get_metadata_dir(); - let metadata_path = get_metadata_path(name); - - // Create the error directory if it does not exist. - try!(create_dir_all(&metadata_dir)); - - // Check each file in the metadata directory. - for entry in try!(read_dir(&metadata_dir)) { - let path = try!(entry).path(); - - // Skip any existing file for this set. - if path == metadata_path { - continue; - } - - // Read the metadata file into a string. - let mut metadata_str = String::new(); - try!( - File::open(&path).and_then(|mut f| - f.read_to_string(&mut metadata_str)) - ); - - // Parse the JSON contents. - let metadata: ErrorMetadataMap = try!(json::decode(&metadata_str)); - - // Check for duplicates. - for err in err_map.keys() { - let err_code = err.as_str(); - if metadata.contains_key(err_code) { - return Ok(Duplicate( - err_code.to_string(), - path.to_string_lossy().into_owned() - )); - } - } - } - - Ok(Unique) +/// Map `name` to a path in the given directory: /.json +fn get_metadata_path(directory: PathBuf, name: &str) -> PathBuf { + directory.join(format!("{}.json", name)) } -/// Write metadata for the errors in `err_map` to disk, to a file corresponding to `name`. -pub fn output_metadata(ecx: &ExtCtxt, name: &str, err_map: &ErrorMap) +/// Write metadata for the errors in `err_map` to disk, to a file corresponding to `prefix/name`. +/// +/// For our current purposes the prefix is the target architecture and the name is a crate name. +/// If an error occurs steps will be taken to ensure that no file is created. +pub fn output_metadata(ecx: &ExtCtxt, prefix: &str, name: &str, err_map: &ErrorMap) -> Result<(), Box> { - let metadata_path = get_metadata_path(name); + // Create the directory to place the file in. + let metadata_dir = get_metadata_dir(prefix); + try!(create_dir_all(&metadata_dir)); - // Open the dump file. - let mut dump_file = try!(OpenOptions::new() - .write(true) - .create(true) - .open(&metadata_path) - ); + // Open the metadata file. + let metadata_path = get_metadata_path(metadata_dir, name); + let mut metadata_file = try!(File::create(&metadata_path)); // Construct a serializable map. let json_map = err_map.iter().map(|(k, &ErrorInfo { description, use_site })| { @@ -150,6 +92,10 @@ pub fn output_metadata(ecx: &ExtCtxt, name: &str, err_map: &ErrorMap) (key, value) }).collect::(); - try!(write!(&mut dump_file, "{}", as_json(&json_map))); - Ok(()) + // Write the data to the file, deleting it if the write fails. + let result = write!(&mut metadata_file, "{}", as_json(&json_map)); + if result.is_err() { + try!(remove_file(&metadata_path)); + } + Ok(try!(result)) } diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 2f7e4a161450a..aee066807f49a 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -10,6 +10,7 @@ use std::cell::RefCell; use std::collections::BTreeMap; +use std::env; use ast; use ast::{Ident, Name, TokenTree}; @@ -20,6 +21,8 @@ use parse::token; use ptr::P; use util::small_vector::SmallVector; +use diagnostics::metadata::output_metadata; + // Maximum width of any line in an extended error description (inclusive). const MAX_DESCRIPTION_WIDTH: usize = 80; @@ -154,7 +157,7 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, token_tree: &[TokenTree]) -> Box { assert_eq!(token_tree.len(), 3); - let (_crate_name, name) = match (&token_tree[0], &token_tree[2]) { + let (crate_name, name) = match (&token_tree[0], &token_tree[2]) { ( // Crate name. &ast::TtToken(_, token::Ident(ref crate_name, _)), @@ -164,9 +167,18 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt, _ => unreachable!() }; - // FIXME (#25705): we used to ensure error code uniqueness and - // output error description JSON metadata here, but the approach - // employed was too brittle. + // Output error metadata to `tmp/extended-errors//.json` + let target_triple = env::var("CFG_COMPILER_HOST_TRIPLE") + .ok().expect("unable to determine target arch from $CFG_COMPILER_HOST_TRIPLE"); + + with_registered_diagnostics(|diagnostics| { + if let Err(e) = output_metadata(ecx, &target_triple, crate_name, &diagnostics) { + ecx.span_bug(span, &format!( + "error writing metadata for triple `{}` and crate `{}`, error: {}, cause: {:?}", + target_triple, crate_name, e.description(), e.cause() + )); + } + }); // Construct the output expression. let (count, expr) =