]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #31680 - arielb1:fast-fulfill, r=nikomatsakis
authorbors <bors@rust-lang.org>
Tue, 16 Feb 2016 22:35:09 +0000 (22:35 +0000)
committerbors <bors@rust-lang.org>
Tue, 16 Feb 2016 22:35:09 +0000 (22:35 +0000)
this improves typeck performance by 5% (LLVM times are still huge).

Basically fixes #25916 (still O(n^2), but the example takes <1s to
compile).

r? @nikomatsakis

40 files changed:
mk/crates.mk
mk/dist.mk
mk/docs.mk
mk/prepare.mk
mk/tests.mk
src/doc/book/vectors.md
src/error-index-generator/main.rs [deleted file]
src/error_index_generator/main.rs [new file with mode: 0644]
src/etc/maketest.py
src/etc/tidy.py
src/libcollections/vec.rs
src/libcore/num/u16.rs
src/libcore/num/u32.rs
src/libcore/num/u64.rs
src/libcore/num/u8.rs
src/libcore/num/uint_macros.rs
src/libcore/num/usize.rs
src/librustc/session/config.rs
src/librustc_back/target/mod.rs
src/librustc_driver/pretty.rs
src/librustc_trans/trans/consts.rs
src/librustdoc/html/layout.rs
src/librustdoc/html/static/main.js
src/libstd/sys/unix/fs.rs
src/libstd/sys/windows/fs.rs
src/libsyntax/parse/parser.rs
src/test/compile-fail/cfg-arg-invalid.rs [new file with mode: 0644]
src/test/compile-fail/non-inline-mod-restriction.rs [new file with mode: 0644]
src/test/run-make/llvm-module-pass/Makefile [deleted file]
src/test/run-make/llvm-module-pass/llvm-pass.so.cc [deleted file]
src/test/run-make/llvm-module-pass/main.rs [deleted file]
src/test/run-make/llvm-module-pass/plugin.rs [deleted file]
src/test/run-make/llvm-pass/Makefile [new file with mode: 0644]
src/test/run-make/llvm-pass/llvm-function-pass.so.cc [new file with mode: 0644]
src/test/run-make/llvm-pass/llvm-module-pass.so.cc [new file with mode: 0644]
src/test/run-make/llvm-pass/main.rs [new file with mode: 0644]
src/test/run-make/llvm-pass/plugin.rs [new file with mode: 0644]
src/test/run-pass/issue-29914-2.rs [new file with mode: 0644]
src/test/run-pass/issue-29914-3.rs [new file with mode: 0644]
src/test/run-pass/issue-29914.rs [new file with mode: 0644]

index bfd054ae988f2f6d2743c21756862eafc8c0b930..cf3e479ec21f7bd08375c27b93b632d6414a3235 100644 (file)
@@ -59,7 +59,7 @@ RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_
                 rustc_data_structures rustc_front rustc_platform_intrinsics \
                 rustc_plugin rustc_metadata rustc_passes
 HOST_CRATES := syntax syntax_ext $(RUSTC_CRATES) rustdoc fmt_macros
-TOOLS := compiletest rustdoc rustc rustbook error-index-generator
+TOOLS := compiletest rustdoc rustc rustbook error_index_generator
 
 DEPS_core :=
 DEPS_alloc := core libc alloc_system
@@ -120,12 +120,12 @@ TOOL_DEPS_compiletest := test getopts
 TOOL_DEPS_rustdoc := rustdoc
 TOOL_DEPS_rustc := rustc_driver
 TOOL_DEPS_rustbook := std rustdoc
-TOOL_DEPS_error-index-generator := rustdoc syntax serialize
+TOOL_DEPS_error_index_generator := rustdoc syntax serialize
 TOOL_SOURCE_compiletest := $(S)src/compiletest/compiletest.rs
 TOOL_SOURCE_rustdoc := $(S)src/driver/driver.rs
 TOOL_SOURCE_rustc := $(S)src/driver/driver.rs
 TOOL_SOURCE_rustbook := $(S)src/rustbook/main.rs
-TOOL_SOURCE_error-index-generator := $(S)src/error-index-generator/main.rs
+TOOL_SOURCE_error_index_generator := $(S)src/error_index_generator/main.rs
 
 ONLY_RLIB_core := 1
 ONLY_RLIB_libc := 1
index 685fb2b5b46792ce6f10da38961e4b6a85efc4ad..31d3764eefab13ca3fdb455037d2aa519d1de599 100644 (file)
@@ -52,7 +52,7 @@ PKG_FILES := \
       doc                                      \
       driver                                   \
       etc                                      \
-      error-index-generator                    \
+      error_index_generator                    \
       $(foreach crate,$(CRATES),lib$(crate))   \
       libcollectionstest                       \
       libcoretest                              \
index 7f73b99863f093fe349962a1b67a72fc159d6f94..83cdb7f8023bcdac86de2ce319bde1c4a1d9a0d1 100644 (file)
@@ -59,8 +59,8 @@ RUSTBOOK_EXE = $(HBIN2_H_$(CFG_BUILD))/rustbook$(X_$(CFG_BUILD))
 # ./configure
 RUSTBOOK = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(RUSTBOOK_EXE)
 
-# The error-index-generator executable...
-ERR_IDX_GEN_EXE = $(HBIN2_H_$(CFG_BUILD))/error-index-generator$(X_$(CFG_BUILD))
+# The error_index_generator executable...
+ERR_IDX_GEN_EXE = $(HBIN2_H_$(CFG_BUILD))/error_index_generator$(X_$(CFG_BUILD))
 ERR_IDX_GEN = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE)
 ERR_IDX_GEN_MD = $(RPATH_VAR2_T_$(CFG_BUILD)_H_$(CFG_BUILD)) $(ERR_IDX_GEN_EXE) markdown
 
@@ -221,9 +221,9 @@ error-index: doc/error-index.html
 # Metadata used to generate the index is created as a side effect of
 # the build so this depends on every crate being up to date.
 doc/error-index.html: $(ERR_IDX_GEN_EXE) $(CSREQ$(2)_T_$(CFG_BUILD)_H_$(CFG_BUILD)) | doc/
-       $(Q)$(call E, error-index-generator: $@)
+       $(Q)$(call E, error_index_generator: $@)
        $(Q)$(ERR_IDX_GEN)
 
 doc/error-index.md: $(ERR_IDX_GEN_EXE) $(CSREQ$(2)_T_$(CFG_BUILD)_H_$(CFG_BUILD)) | doc/
-       $(Q)$(call E, error-index-generator: $@)
+       $(Q)$(call E, error_index_generator: $@)
        $(Q)$(ERR_IDX_GEN_MD)
index 87a445000ada4cc617df2def665a60a935394838..2488de4ad5bdf32850aee70658f6600e3b70f4bc 100644 (file)
@@ -82,7 +82,7 @@ define PREPARE_MAN
 
 endef
 
-PREPARE_TOOLS = $(filter-out compiletest rustbook error-index-generator, $(TOOLS))
+PREPARE_TOOLS = $(filter-out compiletest rustbook error_index_generator, $(TOOLS))
 
 
 # $(1) is tool
index acb75bb7cdc3b0ced461a73676972e5b6b5cb16b..b887f7b887f2a0b5a4d93a7556e2e063ebd797b0 100644 (file)
@@ -1072,7 +1072,8 @@ $(3)/test/run-make/%-$(1)-T-$(2)-H-$(3).ok: \
            $(3) \
            "$$(LLVM_LIBDIR_RUSTFLAGS_$(3))" \
            "$$(LLVM_ALL_COMPONENTS_$(3))" \
-           "$$(LLVM_CXXFLAGS_$(3))"
+           "$$(LLVM_CXXFLAGS_$(3))" \
+           '$$(CXX_$(3))'
        @touch -r $$@.start_time $$@ && rm $$@.start_time
 else
 # FIXME #11094 - The above rule doesn't work right for multiple targets
index b09735c3feee6b9d12c7816fe06c8adafa6933d0..f5a543d75b1b40baecb74f5605172b36157a4c0c 100644 (file)
@@ -11,8 +11,8 @@ let v = vec![1, 2, 3, 4, 5]; // v: Vec<i32>
 ```
 
 (Notice that unlike the `println!` macro we’ve used in the past, we use square
-brackets `[]` with `vec!` macro. Rust allows you to use either in either situation,
-this is just convention.)
+brackets `[]` with `vec!` macro. Rust allows you to use either in either
+situation, this is just convention.)
 
 There’s an alternate form of `vec!` for repeating an initial value:
 
@@ -20,6 +20,12 @@ There’s an alternate form of `vec!` for repeating an initial value:
 let v = vec![0; 10]; // ten zeroes
 ```
 
+Vectors store their contents as contiguous arrays of `T` on the heap. This means
+that they must be able to know the size of `T` at compile time (that is, how
+many bytes are needed to store a `T`?). The size of some things can't be known
+at compile time. For these you'll have to store a pointer to that thing:
+thankfully, the [`Box`][box] type works perfectly for this.
+
 ## Accessing elements
 
 To get the value at a particular index in the vector, we use `[]`s:
@@ -113,6 +119,7 @@ Vectors have many more useful methods, which you can read about in [their
 API documentation][vec].
 
 [vec]: ../std/vec/index.html
+[box]: ../std/boxed/index.html
 [generic]: generics.html
 [panic]: concurrency.html#panics
 [get]: http://doc.rust-lang.org/std/vec/struct.Vec.html#method.get
diff --git a/src/error-index-generator/main.rs b/src/error-index-generator/main.rs
deleted file mode 100644 (file)
index db9dd00..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(rustc_private, rustdoc)]
-
-extern crate syntax;
-extern crate rustdoc;
-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;
-
-use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
-
-use rustdoc::html::markdown::Markdown;
-use rustc_serialize::json;
-
-enum OutputFormat {
-    HTML(HTMLFormatter),
-    Markdown(MarkdownFormatter),
-    Unknown(String),
-}
-
-impl OutputFormat {
-    fn from(format: &str) -> OutputFormat {
-        match &*format.to_lowercase() {
-            "html"     => OutputFormat::HTML(HTMLFormatter),
-            "markdown" => OutputFormat::Markdown(MarkdownFormatter),
-            s          => OutputFormat::Unknown(s.to_owned()),
-        }
-    }
-}
-
-trait Formatter {
-    fn header(&self, output: &mut Write) -> Result<(), Box<Error>>;
-    fn title(&self, output: &mut Write) -> Result<(), Box<Error>>;
-    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
-                        err_code: &str) -> Result<(), Box<Error>>;
-    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>>;
-}
-
-struct HTMLFormatter;
-struct MarkdownFormatter;
-
-impl Formatter for HTMLFormatter {
-    fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
-        try!(write!(output, r##"<!DOCTYPE html>
-<html>
-<head>
-<title>Rust Compiler Error Index</title>
-<meta charset="utf-8">
-<!-- Include rust.css after main.css so its rules take priority. -->
-<link rel="stylesheet" type="text/css" href="main.css"/>
-<link rel="stylesheet" type="text/css" href="rust.css"/>
-<style>
-.error-undescribed {{
-    display: none;
-}}
-</style>
-</head>
-<body>
-"##));
-        Ok(())
-    }
-
-    fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
-        try!(write!(output, "<h1>Rust Compiler Error Index</h1>\n"));
-        Ok(())
-    }
-
-    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
-                        err_code: &str) -> Result<(), Box<Error>> {
-        // Enclose each error in a div so they can be shown/hidden en masse.
-        let desc_desc = match info.description {
-            Some(_) => "error-described",
-            None => "error-undescribed",
-        };
-        let use_desc = match info.use_site {
-            Some(_) => "error-used",
-            None => "error-unused",
-        };
-        try!(write!(output, "<div class=\"{} {}\">", desc_desc, use_desc));
-
-        // Error title (with self-link).
-        try!(write!(output,
-                    "<h2 id=\"{0}\" class=\"section-header\"><a href=\"#{0}\">{0}</a></h2>\n",
-                    err_code));
-
-        // Description rendered as markdown.
-        match info.description {
-            Some(ref desc) => try!(write!(output, "{}", Markdown(desc))),
-            None => try!(write!(output, "<p>No description.</p>\n")),
-        }
-
-        try!(write!(output, "</div>\n"));
-        Ok(())
-    }
-
-    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
-        try!(write!(output, "</body>\n</html>"));
-        Ok(())
-    }
-}
-
-impl Formatter for MarkdownFormatter {
-    #[allow(unused_variables)]
-    fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
-        Ok(())
-    }
-
-    fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
-        try!(write!(output, "# Rust Compiler Error Index\n"));
-        Ok(())
-    }
-
-    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
-                        err_code: &str) -> Result<(), Box<Error>> {
-        Ok(match info.description {
-            Some(ref desc) => try!(write!(output, "## {}\n{}\n", err_code, desc)),
-            None => (),
-        })
-    }
-
-    #[allow(unused_variables)]
-    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
-        Ok(())
-    }
-}
-
-/// Load all the metadata files from `metadata_dir` into an in-memory map.
-fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
-    let mut all_errors = BTreeMap::new();
-
-    for entry in try!(read_dir(metadata_dir)) {
-        let path = try!(entry).path();
-
-        let mut metadata_str = String::new();
-        try!(File::open(&path).and_then(|mut f| f.read_to_string(&mut metadata_str)));
-
-        let some_errors: ErrorMetadataMap = try!(json::decode(&metadata_str));
-
-        for (err_code, info) in some_errors {
-            all_errors.insert(err_code, info);
-        }
-    }
-
-    Ok(all_errors)
-}
-
-/// Output an HTML page for the errors in `err_map` to `output_path`.
-fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
-                                   formatter: T) -> Result<(), Box<Error>> {
-    let mut output_file = try!(File::create(output_path));
-
-    try!(formatter.header(&mut output_file));
-    try!(formatter.title(&mut output_file));
-
-    for (err_code, info) in err_map {
-        try!(formatter.error_code_block(&mut output_file, info, err_code));
-    }
-
-    formatter.footer(&mut output_file)
-}
-
-fn main_with_result(format: OutputFormat) -> Result<(), Box<Error>> {
-    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));
-    match format {
-        OutputFormat::Unknown(s)  => panic!("Unknown output format: {}", s),
-        OutputFormat::HTML(h)     => try!(render_error_page(&err_map,
-                                                            Path::new("doc/error-index.html"),
-                                                            h)),
-        OutputFormat::Markdown(m) => try!(render_error_page(&err_map,
-                                                            Path::new("doc/error-index.md"),
-                                                            m)),
-    }
-    Ok(())
-}
-
-fn parse_args() -> OutputFormat {
-    for arg in env::args().skip(1) {
-        return OutputFormat::from(&arg);
-    }
-    OutputFormat::from("html")
-}
-
-fn main() {
-    if let Err(e) = main_with_result(parse_args()) {
-        panic!("{}", e.description());
-    }
-}
diff --git a/src/error_index_generator/main.rs b/src/error_index_generator/main.rs
new file mode 100644 (file)
index 0000000..db9dd00
--- /dev/null
@@ -0,0 +1,203 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(rustc_private, rustdoc)]
+
+extern crate syntax;
+extern crate rustdoc;
+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;
+
+use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata};
+
+use rustdoc::html::markdown::Markdown;
+use rustc_serialize::json;
+
+enum OutputFormat {
+    HTML(HTMLFormatter),
+    Markdown(MarkdownFormatter),
+    Unknown(String),
+}
+
+impl OutputFormat {
+    fn from(format: &str) -> OutputFormat {
+        match &*format.to_lowercase() {
+            "html"     => OutputFormat::HTML(HTMLFormatter),
+            "markdown" => OutputFormat::Markdown(MarkdownFormatter),
+            s          => OutputFormat::Unknown(s.to_owned()),
+        }
+    }
+}
+
+trait Formatter {
+    fn header(&self, output: &mut Write) -> Result<(), Box<Error>>;
+    fn title(&self, output: &mut Write) -> Result<(), Box<Error>>;
+    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
+                        err_code: &str) -> Result<(), Box<Error>>;
+    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>>;
+}
+
+struct HTMLFormatter;
+struct MarkdownFormatter;
+
+impl Formatter for HTMLFormatter {
+    fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
+        try!(write!(output, r##"<!DOCTYPE html>
+<html>
+<head>
+<title>Rust Compiler Error Index</title>
+<meta charset="utf-8">
+<!-- Include rust.css after main.css so its rules take priority. -->
+<link rel="stylesheet" type="text/css" href="main.css"/>
+<link rel="stylesheet" type="text/css" href="rust.css"/>
+<style>
+.error-undescribed {{
+    display: none;
+}}
+</style>
+</head>
+<body>
+"##));
+        Ok(())
+    }
+
+    fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
+        try!(write!(output, "<h1>Rust Compiler Error Index</h1>\n"));
+        Ok(())
+    }
+
+    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
+                        err_code: &str) -> Result<(), Box<Error>> {
+        // Enclose each error in a div so they can be shown/hidden en masse.
+        let desc_desc = match info.description {
+            Some(_) => "error-described",
+            None => "error-undescribed",
+        };
+        let use_desc = match info.use_site {
+            Some(_) => "error-used",
+            None => "error-unused",
+        };
+        try!(write!(output, "<div class=\"{} {}\">", desc_desc, use_desc));
+
+        // Error title (with self-link).
+        try!(write!(output,
+                    "<h2 id=\"{0}\" class=\"section-header\"><a href=\"#{0}\">{0}</a></h2>\n",
+                    err_code));
+
+        // Description rendered as markdown.
+        match info.description {
+            Some(ref desc) => try!(write!(output, "{}", Markdown(desc))),
+            None => try!(write!(output, "<p>No description.</p>\n")),
+        }
+
+        try!(write!(output, "</div>\n"));
+        Ok(())
+    }
+
+    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
+        try!(write!(output, "</body>\n</html>"));
+        Ok(())
+    }
+}
+
+impl Formatter for MarkdownFormatter {
+    #[allow(unused_variables)]
+    fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
+        Ok(())
+    }
+
+    fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
+        try!(write!(output, "# Rust Compiler Error Index\n"));
+        Ok(())
+    }
+
+    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
+                        err_code: &str) -> Result<(), Box<Error>> {
+        Ok(match info.description {
+            Some(ref desc) => try!(write!(output, "## {}\n{}\n", err_code, desc)),
+            None => (),
+        })
+    }
+
+    #[allow(unused_variables)]
+    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
+        Ok(())
+    }
+}
+
+/// Load all the metadata files from `metadata_dir` into an in-memory map.
+fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
+    let mut all_errors = BTreeMap::new();
+
+    for entry in try!(read_dir(metadata_dir)) {
+        let path = try!(entry).path();
+
+        let mut metadata_str = String::new();
+        try!(File::open(&path).and_then(|mut f| f.read_to_string(&mut metadata_str)));
+
+        let some_errors: ErrorMetadataMap = try!(json::decode(&metadata_str));
+
+        for (err_code, info) in some_errors {
+            all_errors.insert(err_code, info);
+        }
+    }
+
+    Ok(all_errors)
+}
+
+/// Output an HTML page for the errors in `err_map` to `output_path`.
+fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
+                                   formatter: T) -> Result<(), Box<Error>> {
+    let mut output_file = try!(File::create(output_path));
+
+    try!(formatter.header(&mut output_file));
+    try!(formatter.title(&mut output_file));
+
+    for (err_code, info) in err_map {
+        try!(formatter.error_code_block(&mut output_file, info, err_code));
+    }
+
+    formatter.footer(&mut output_file)
+}
+
+fn main_with_result(format: OutputFormat) -> Result<(), Box<Error>> {
+    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));
+    match format {
+        OutputFormat::Unknown(s)  => panic!("Unknown output format: {}", s),
+        OutputFormat::HTML(h)     => try!(render_error_page(&err_map,
+                                                            Path::new("doc/error-index.html"),
+                                                            h)),
+        OutputFormat::Markdown(m) => try!(render_error_page(&err_map,
+                                                            Path::new("doc/error-index.md"),
+                                                            m)),
+    }
+    Ok(())
+}
+
+fn parse_args() -> OutputFormat {
+    for arg in env::args().skip(1) {
+        return OutputFormat::from(&arg);
+    }
+    OutputFormat::from("html")
+}
+
+fn main() {
+    if let Err(e) = main_with_result(parse_args()) {
+        panic!("{}", e.description());
+    }
+}
index 1687838289babc0bd42cb11587fa995864e07435..c7d17b23bffff6f9f467ea2fadc5f674b86b9eb7 100644 (file)
@@ -57,6 +57,7 @@ putenv('S', os.path.abspath(sys.argv[13]))
 putenv('RUSTFLAGS', sys.argv[15])
 putenv('LLVM_COMPONENTS', sys.argv[16])
 putenv('LLVM_CXXFLAGS', sys.argv[17])
+putenv('CXX', sys.argv[18])
 putenv('PYTHON', sys.executable)
 os.putenv('TARGET', target_triple)
 
index fd3f4bf0b13b1111f57a7e2ba3d394821b443663..ea34a803ccb4054a18c133ca8436cbb3cd920f08 100644 (file)
@@ -24,6 +24,15 @@ linelength_flag = "ignore-tidy-linelength"
 
 interesting_files = ['.rs', '.py', '.js', '.sh', '.c', '.h']
 uninteresting_files = ['miniz.c', 'jquery', 'rust_android_dummy']
+stable_whitelist = {
+    'src/bootstrap',
+    'src/build_helper',
+    'src/libcollectionstest',
+    'src/libcore',
+    'src/libstd',
+    'src/rustc/std_shim',
+    'src/test'
+}
 
 
 def report_error_name_no(name, no, s):
@@ -93,6 +102,7 @@ count_other_linted_files = 0
 file_counts = {ext: 0 for ext in interesting_files}
 
 all_paths = set()
+needs_unstable_attr = set()
 
 try:
     for (dirpath, dirnames, filenames) in os.walk(src_dir):
@@ -149,6 +159,9 @@ try:
                 else:
                     if "SNAP " in line:
                         report_warn("unmatched SNAP line: " + line)
+                search = re.search(r'^#!\[unstable', line)
+                if search:
+                    needs_unstable_attr.discard(filename)
 
             if cr_flag in line:
                 check_cr = False
@@ -181,6 +194,9 @@ try:
                 check_cr = True
                 check_tab = True
                 check_linelength = True
+                if all(f not in filename for f in stable_whitelist) and \
+                   re.search(r'src/.*/lib\.rs', filename):
+                    needs_unstable_attr.add(filename)
 
             # Put a reasonable limit on the amount of header data we use for
             # the licenseck
@@ -195,6 +211,8 @@ try:
         update_counts(current_name)
         assert len(current_contents) > 0
         do_license_check(current_name, current_contents)
+    for f in needs_unstable_attr:
+        report_error_name_no(f, 1, "requires unstable attribute")
 
 except UnicodeDecodeError as e:
     report_err("UTF-8 decoding error " + str(e))
index 1bc9e6588adb39835cab4df74320d1669194417a..270a01014c14b0051523f0ce2c2800e1317113ca 100644 (file)
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-//! A growable list type with heap-allocated contents, written `Vec<T>` but
-//! pronounced 'vector.'
+//! A contiguous growable array type with heap-allocated contents, written
+//! `Vec<T>` but pronounced 'vector.'
 //!
 //! Vectors have `O(1)` indexing, amortized `O(1)` push (to the end) and
 //! `O(1)` pop (from the end).
@@ -78,7 +78,7 @@
 
 use super::range::RangeArgument;
 
-/// A growable list type, written `Vec<T>` but pronounced 'vector.'
+/// A contiguous growable array type, written `Vec<T>` but pronounced 'vector.'
 ///
 /// # Examples
 ///
index 68e50e8a400ea021a472b0542c64509c7eaa976c..d7e320267c60777c8dafa3a304a36db74cf0d771 100644 (file)
@@ -14,4 +14,4 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-uint_module! { u16, i16, 16 }
+uint_module! { u16, 16 }
index c1ee96b363c27783e016f113c6a59b54e0a3f651..9a26a39d5b36546b2f22c2ab1998dcbf346bfdcf 100644 (file)
@@ -14,4 +14,4 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-uint_module! { u32, i32, 32 }
+uint_module! { u32, 32 }
index c0d18d850a796d9a841c17f85c448a42f5becb47..e12c2c265420bcef49127a67cbbb10da64d7aa78 100644 (file)
@@ -14,4 +14,4 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-uint_module! { u64, i64, 64 }
+uint_module! { u64, 64 }
index a60c480d810ea4e20be74b5add6271c9e95c7760..0eb63bd9f3a9d863b74a7951958915e2bdab935a 100644 (file)
@@ -14,4 +14,4 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-uint_module! { u8, i8, 8 }
+uint_module! { u8, 8 }
index 16d84cf81e11db8a74608c2ebd9f3404476e65fa..9539a311390f6407e96c7456c61839adf232df46 100644 (file)
@@ -10,7 +10,7 @@
 
 #![doc(hidden)]
 
-macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
+macro_rules! uint_module { ($T:ty, $bits:expr) => (
 
 #[unstable(feature = "num_bits_bytes",
            reason = "may want to be an associated function",
index a6a7be023ebf4e3851fff0372f51090f54b21e7a..875ab32fa8c572efdd9d5339128b55d27926b320 100644 (file)
@@ -15,6 +15,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 #[cfg(target_pointer_width = "32")]
-uint_module! { usize, isize, 32 }
+uint_module! { usize, 32 }
 #[cfg(target_pointer_width = "64")]
-uint_module! { usize, isize, 64 }
+uint_module! { usize, 64 }
index c96713a72851a3ff930e06eef53bdc70d49e2d5c..864ff40fe10748479c01939c744e0f39afe8240b 100644 (file)
@@ -28,6 +28,7 @@
 use syntax::attr::AttrMetaMethods;
 use syntax::errors::{ColorConfig, Handler};
 use syntax::parse;
+use syntax::parse::lexer::Reader;
 use syntax::parse::token::InternedString;
 use syntax::feature_gate::UnstableFeatures;
 
@@ -509,7 +510,7 @@ fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
     link_args: Option<Vec<String>> = (None, parse_opt_list,
         "extra arguments to pass to the linker (space separated)"),
     link_dead_code: bool = (false, parse_bool,
-        "let the linker strip dead coded (turning it on can be used for code coverage)"),
+        "don't let linker strip dead code (turning it on can be used for code coverage)"),
     lto: bool = (false, parse_bool,
         "perform LLVM link-time optimizations"),
     target_cpu: Option<String> = (None, parse_opt_string,
@@ -906,10 +907,19 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
 // Convert strings provided as --cfg [cfgspec] into a crate_cfg
 pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
     cfgspecs.into_iter().map(|s| {
-        parse::parse_meta_from_source_str("cfgspec".to_string(),
-                                          s.to_string(),
-                                          Vec::new(),
-                                          &parse::ParseSess::new())
+        let sess = parse::ParseSess::new();
+        let mut parser = parse::new_parser_from_source_str(&sess,
+                                                           Vec::new(),
+                                                           "cfgspec".to_string(),
+                                                           s.to_string());
+        let meta_item = panictry!(parser.parse_meta_item());
+
+        if !parser.reader.is_eof() {
+            early_error(ErrorOutputType::default(), &format!("invalid --cfg argument: {}",
+                                                             s))
+        }
+
+        meta_item
     }).collect::<ast::CrateConfig>()
 }
 
index a868178b14fb9d8aabcc8b2dc737926ef5a95133..e0743c339ce9d152caaf4091a8e32227b9214dee 100644 (file)
 
 macro_rules! supported_targets {
     ( $(($triple:expr, $module:ident)),+ ) => (
+        $(mod $module;)*
+
         /// List of supported targets
         pub const TARGETS: &'static [&'static str] = &[$($triple),*];
 
         // this would use a match if stringify! were allowed in pattern position
         fn load_specific(target: &str) -> Option<Target> {
-            $(mod $module;)*
             let target = target.replace("-", "_");
             if false { }
             $(
index 4a82aa7282599e2c18c5c65c172492f7e2c0a38f..0517357892161c6ffdb1da1bbeb460841292f88d 100644 (file)
@@ -30,6 +30,8 @@
 use rustc_resolve as resolve;
 use rustc_metadata::cstore::CStore;
 
+use rustc_mir::pretty::write_mir_pretty;
+
 use syntax::ast::{self, BlockCheckMode};
 use syntax::codemap;
 use syntax::fold::{self, Folder};
@@ -77,6 +79,7 @@ pub enum PpMode {
     PpmSource(PpSourceMode),
     PpmHir(PpSourceMode),
     PpmFlowGraph(PpFlowGraphMode),
+    PpmMir,
 }
 
 pub fn parse_pretty(sess: &Session,
@@ -96,6 +99,7 @@ pub fn parse_pretty(sess: &Session,
         ("hir", true) => PpmHir(PpmNormal),
         ("hir,identified", true) => PpmHir(PpmIdentified),
         ("hir,typed", true) => PpmHir(PpmTyped),
+        ("mir", true) => PpmMir,
         ("flowgraph", true) => PpmFlowGraph(PpFlowGraphMode::Default),
         ("flowgraph,unlabelled", true) => PpmFlowGraph(PpFlowGraphMode::UnlabelledEdges),
         _ => {
@@ -103,7 +107,7 @@ pub fn parse_pretty(sess: &Session,
                 sess.fatal(&format!("argument to `unpretty` must be one of `normal`, \
                                      `expanded`, `flowgraph[,unlabelled]=<nodeid>`, \
                                      `identified`, `expanded,identified`, `everybody_loops`, \
-                                     `hir`, `hir,identified`, or `hir,typed`; got {}",
+                                     `hir`, `hir,identified`, `hir,typed`, or `mir`; got {}",
                                     name));
             } else {
                 sess.fatal(&format!("argument to `pretty` must be one of `normal`, `expanded`, \
@@ -569,6 +573,7 @@ fn needs_ast_map(ppm: &PpMode, opt_uii: &Option<UserIdentifiedItem>) -> bool {
         PpmSource(PpmExpandedIdentified) |
         PpmSource(PpmExpandedHygiene) |
         PpmHir(_) |
+        PpmMir |
         PpmFlowGraph(_) => true,
         PpmSource(PpmTyped) => panic!("invalid state"),
     }
@@ -584,6 +589,7 @@ fn needs_expansion(ppm: &PpMode) -> bool {
         PpmSource(PpmExpandedIdentified) |
         PpmSource(PpmExpandedHygiene) |
         PpmHir(_) |
+        PpmMir |
         PpmFlowGraph(_) => true,
         PpmSource(PpmTyped) => panic!("invalid state"),
     }
@@ -801,6 +807,48 @@ pub fn pretty_print_input(sess: Session,
             })
         }
 
+        (PpmMir, None) => {
+            debug!("pretty printing MIR for whole crate");
+            let ast_map = ast_map.expect("--unpretty mir missing ast_map");
+            abort_on_err(driver::phase_3_run_analysis_passes(&sess,
+                                                             &cstore,
+                                                             ast_map,
+                                                             &arenas,
+                                                             &id,
+                                                             resolve::MakeGlobMap::No,
+                                                             |tcx, mir_map, _, _| {
+                let mir_map = mir_map.unwrap();
+
+                for (nodeid, mir) in &mir_map.map {
+                    try!(writeln!(out, "MIR for {}", tcx.map.node_to_string(*nodeid)));
+                    try!(write_mir_pretty(mir, &mut out));
+                }
+
+                Ok(())
+            }), &sess)
+        }
+
+        (PpmMir, Some(uii)) => {
+            debug!("pretty printing MIR for {:?}", uii);
+            let ast_map = ast_map.expect("--unpretty mir missing ast_map");
+            let nodeid = uii.to_one_node_id("--unpretty", &sess, &ast_map);
+
+            abort_on_err(driver::phase_3_run_analysis_passes(&sess,
+                                                             &cstore,
+                                                             ast_map,
+                                                             &arenas,
+                                                             &id,
+                                                             resolve::MakeGlobMap::No,
+                                                             |tcx, mir_map, _, _| {
+                let mir_map = mir_map.unwrap();
+                try!(writeln!(out, "MIR for {}", tcx.map.node_to_string(nodeid)));
+                let mir = mir_map.map.get(&nodeid).unwrap_or_else(|| {
+                    sess.fatal(&format!("no MIR map entry for node {}", nodeid))
+                });
+                write_mir_pretty(mir, &mut out)
+            }), &sess)
+        }
+
         (PpmFlowGraph(mode), opt_uii) => {
             debug!("pretty printing flow graph for {:?}", opt_uii);
             let uii = opt_uii.unwrap_or_else(|| {
index 4f25091d343c85e9984dce0ce2cc05f3e0cbbdb6..e8c90fa31eac22bf30b9c189b58b1e989a90205c 100644 (file)
@@ -24,8 +24,6 @@
 use middle::const_eval::{const_int_checked_rem, const_uint_checked_rem};
 use middle::const_eval::{const_int_checked_shl, const_uint_checked_shl};
 use middle::const_eval::{const_int_checked_shr, const_uint_checked_shr};
-use middle::const_eval::EvalHint::ExprTypeChecked;
-use middle::const_eval::eval_const_expr_partial;
 use middle::def::Def;
 use middle::def_id::DefId;
 use trans::{adt, closure, debuginfo, expr, inline, machine};
@@ -261,7 +259,7 @@ pub fn description(&self) -> Cow<str> {
     }
 }
 
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum TrueConst {
     Yes, No
 }
@@ -665,11 +663,11 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         },
         hir::ExprIndex(ref base, ref index) => {
             let (bv, bt) = try!(const_expr(cx, &base, param_substs, fn_args, trueconst));
-            let iv = match eval_const_expr_partial(cx.tcx(), &index, ExprTypeChecked, None) {
-                Ok(ConstVal::Int(i)) => i as u64,
-                Ok(ConstVal::Uint(u)) => u,
-                _ => cx.sess().span_bug(index.span,
-                                        "index is not an integer-constant expression")
+            let iv = try!(const_expr(cx, &index, param_substs, fn_args, TrueConst::Yes)).0;
+            let iv = if let Some(iv) = const_to_opt_uint(iv) {
+                iv
+            } else {
+                cx.sess().span_bug(index.span, "index is not an integer-constant expression");
             };
             let (arr, len) = match bt.sty {
                 ty::TyArray(_, u) => (bv, C_uint(cx, u)),
index ffcd22fa8209604daeda1542306d22cc1e13c07a..975b4d3636f2d10b983fb0a79c61b6d92d550c01 100644 (file)
@@ -122,7 +122,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
 
                 <p>
                     Search functions by type signature (e.g.
-                    <code>vec -> usize</code>)
+                    <code>vec -> usize</code> or <code>* -> vec</code>)
                 </p>
             </div>
         </div>
index 8844ed82bb5e29cd73c956d28ad56bee6d1a7451..08f70ae9ce7a0ec1896c7442a2cf50b43566ddfa 100644 (file)
                 var parts = val.split("->").map(trimmer);
                 var input = parts[0];
                 // sort inputs so that order does not matter
-                var inputs = input.split(",").map(trimmer).sort();
+                var inputs = input.split(",").map(trimmer).sort().toString();
                 var output = parts[1];
 
                 for (var i = 0; i < nSearchWords; ++i) {
 
                     // allow searching for void (no output) functions as well
                     var typeOutput = type.output ? type.output.name : "";
-                    if (inputs.toString() === typeInputs.toString() &&
-                        output == typeOutput) {
+                    if ((inputs === "*" || inputs === typeInputs.toString()) &&
+                        (output === "*" || output == typeOutput)) {
                         results.push({id: i, index: -1, dontValidate: true});
                     }
                 }
index 14f30a6257660bcf4ffa31819c1ce15b09103f4f..e8e0a604e552e0c60fee49f46620f23a989002e2 100644 (file)
@@ -15,7 +15,7 @@
 use ffi::{CString, CStr, OsString, OsStr};
 use fmt;
 use io::{self, Error, ErrorKind, SeekFrom};
-use libc::{self, dirent, c_int, off_t, mode_t};
+use libc::{self, c_int, mode_t};
 use mem;
 use path::{Path, PathBuf};
 use ptr;
 use sys_common::{AsInner, FromInner};
 
 #[cfg(target_os = "linux")]
-use libc::{stat64, fstat64, lstat64};
+use libc::{stat64, fstat64, lstat64, off64_t, ftruncate64, lseek64, dirent64, readdir64_r, open64};
 #[cfg(not(target_os = "linux"))]
-use libc::{stat as stat64, fstat as fstat64, lstat as lstat64};
+use libc::{stat as stat64, fstat as fstat64, lstat as lstat64, off_t as off64_t,
+           ftruncate as ftruncate64, lseek as lseek64, dirent as dirent64, open as open64};
+#[cfg(not(any(target_os = "linux", target_os = "solaris")))]
+use libc::{readdir_r as readdir64_r};
 
 pub struct File(FileDesc);
 
@@ -48,7 +51,7 @@ unsafe impl Send for Dir {}
 unsafe impl Sync for Dir {}
 
 pub struct DirEntry {
-    entry: dirent,
+    entry: dirent64,
     root: Arc<PathBuf>,
     // We need to store an owned copy of the directory name
     // on Solaris because a) it uses a zero-length array to
@@ -223,7 +226,7 @@ fn next(&mut self) -> Option<io::Result<DirEntry>> {
             };
             let mut entry_ptr = ptr::null_mut();
             loop {
-                if libc::readdir_r(self.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
+                if readdir64_r(self.dirp.0, &mut ret.entry, &mut entry_ptr) != 0 {
                     return Some(Err(Error::last_os_error()))
                 }
                 if entry_ptr.is_null() {
@@ -394,7 +397,7 @@ pub fn open_c(path: &CStr, opts: &OpenOptions) -> io::Result<File> {
                     try!(opts.get_creation_mode()) |
                     (opts.custom_flags as c_int & !libc::O_ACCMODE);
         let fd = try!(cvt_r(|| unsafe {
-            libc::open(path.as_ptr(), flags, opts.mode as c_int)
+            open64(path.as_ptr(), flags, opts.mode as c_int)
         }));
         let fd = FileDesc::new(fd);
 
@@ -443,7 +446,7 @@ unsafe fn os_datasync(fd: c_int) -> c_int { libc::fsync(fd) }
 
     pub fn truncate(&self, size: u64) -> io::Result<()> {
         try!(cvt_r(|| unsafe {
-            libc::ftruncate(self.0.raw(), size as libc::off_t)
+            ftruncate64(self.0.raw(), size as off64_t)
         }));
         Ok(())
     }
@@ -460,11 +463,11 @@ pub fn flush(&self) -> io::Result<()> { Ok(()) }
 
     pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
         let (whence, pos) = match pos {
-            SeekFrom::Start(off) => (libc::SEEK_SET, off as off_t),
-            SeekFrom::End(off) => (libc::SEEK_END, off as off_t),
-            SeekFrom::Current(off) => (libc::SEEK_CUR, off as off_t),
+            SeekFrom::Start(off) => (libc::SEEK_SET, off as off64_t),
+            SeekFrom::End(off) => (libc::SEEK_END, off as off64_t),
+            SeekFrom::Current(off) => (libc::SEEK_CUR, off as off64_t),
         };
-        let n = try!(cvt(unsafe { libc::lseek(self.0.raw(), pos, whence) }));
+        let n = try!(cvt(unsafe { lseek64(self.0.raw(), pos, whence) }));
         Ok(n as u64)
     }
 
index d4d95a12f81c42a00be3d76007f6ff2e6990df4e..95fb1e7c60052c27d2355153a9178a11a6d40cd7 100644 (file)
@@ -30,7 +30,11 @@ pub struct File { handle: Handle }
 
 #[derive(Clone)]
 pub struct FileAttr {
-    data: c::WIN32_FILE_ATTRIBUTE_DATA,
+    attributes: c::DWORD,
+    creation_time: c::FILETIME,
+    last_access_time: c::FILETIME,
+    last_write_time: c::FILETIME,
+    file_size: u64,
     reparse_tag: c::DWORD,
 }
 
@@ -142,14 +146,11 @@ pub fn file_type(&self) -> io::Result<FileType> {
 
     pub fn metadata(&self) -> io::Result<FileAttr> {
         Ok(FileAttr {
-            data: c::WIN32_FILE_ATTRIBUTE_DATA {
-                dwFileAttributes: self.data.dwFileAttributes,
-                ftCreationTime: self.data.ftCreationTime,
-                ftLastAccessTime: self.data.ftLastAccessTime,
-                ftLastWriteTime: self.data.ftLastWriteTime,
-                nFileSizeHigh: self.data.nFileSizeHigh,
-                nFileSizeLow: self.data.nFileSizeLow,
-            },
+            attributes: self.data.dwFileAttributes,
+            creation_time: self.data.ftCreationTime,
+            last_access_time: self.data.ftLastAccessTime,
+            last_write_time: self.data.ftLastWriteTime,
+            file_size: ((self.data.nFileSizeHigh as u64) << 32) | (self.data.nFileSizeLow as u64),
             reparse_tag: if self.data.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
                     // reserved unless this is a reparse point
                     self.data.dwReserved0
@@ -290,14 +291,11 @@ pub fn file_attr(&self) -> io::Result<FileAttr> {
             try!(cvt(c::GetFileInformationByHandle(self.handle.raw(),
                                                    &mut info)));
             let mut attr = FileAttr {
-                data: c::WIN32_FILE_ATTRIBUTE_DATA {
-                    dwFileAttributes: info.dwFileAttributes,
-                    ftCreationTime: info.ftCreationTime,
-                    ftLastAccessTime: info.ftLastAccessTime,
-                    ftLastWriteTime: info.ftLastWriteTime,
-                    nFileSizeHigh: info.nFileSizeHigh,
-                    nFileSizeLow: info.nFileSizeLow,
-                },
+                attributes: info.dwFileAttributes,
+                creation_time: info.ftCreationTime,
+                last_access_time: info.ftLastAccessTime,
+                last_write_time: info.ftLastWriteTime,
+                file_size: ((info.nFileSizeHigh as u64) << 32) | (info.nFileSizeLow as u64),
                 reparse_tag: 0,
             };
             if attr.is_reparse_point() {
@@ -420,45 +418,45 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl FileAttr {
     pub fn size(&self) -> u64 {
-        ((self.data.nFileSizeHigh as u64) << 32) | (self.data.nFileSizeLow as u64)
+        self.file_size
     }
 
     pub fn perm(&self) -> FilePermissions {
-        FilePermissions { attrs: self.data.dwFileAttributes }
+        FilePermissions { attrs: self.attributes }
     }
 
-    pub fn attrs(&self) -> u32 { self.data.dwFileAttributes as u32 }
+    pub fn attrs(&self) -> u32 { self.attributes as u32 }
 
     pub fn file_type(&self) -> FileType {
-        FileType::new(self.data.dwFileAttributes, self.reparse_tag)
+        FileType::new(self.attributes, self.reparse_tag)
     }
 
     pub fn modified(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(self.data.ftLastWriteTime))
+        Ok(SystemTime::from(self.last_write_time))
     }
 
     pub fn accessed(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(self.data.ftLastAccessTime))
+        Ok(SystemTime::from(self.last_access_time))
     }
 
     pub fn created(&self) -> io::Result<SystemTime> {
-        Ok(SystemTime::from(self.data.ftCreationTime))
+        Ok(SystemTime::from(self.creation_time))
     }
 
     pub fn modified_u64(&self) -> u64 {
-        to_u64(&self.data.ftLastWriteTime)
+        to_u64(&self.last_write_time)
     }
 
     pub fn accessed_u64(&self) -> u64 {
-        to_u64(&self.data.ftLastAccessTime)
+        to_u64(&self.last_access_time)
     }
 
     pub fn created_u64(&self) -> u64 {
-        to_u64(&self.data.ftCreationTime)
+        to_u64(&self.creation_time)
     }
 
     fn is_reparse_point(&self) -> bool {
-        self.data.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0
+        self.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0
     }
 }
 
index 59e79200568a05f46144b5875a545028c96b5e52..a5f998b318e346d250fd6ab3100f387318fe68c6 100644 (file)
@@ -72,6 +72,7 @@
     flags Restrictions: u8 {
         const RESTRICTION_STMT_EXPR         = 1 << 0,
         const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1,
+        const NO_NONINLINE_MOD  = 1 << 2,
     }
 }
 
@@ -3301,8 +3302,8 @@ pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
     /// Evaluate the closure with restrictions in place.
     ///
     /// After the closure is evaluated, restrictions are reset.
-    pub fn with_res<F>(&mut self, r: Restrictions, f: F) -> PResult<'a, P<Expr>>
-        where F: FnOnce(&mut Self) -> PResult<'a,  P<Expr>>
+    pub fn with_res<F, T>(&mut self, r: Restrictions, f: F) -> T
+        where F: FnOnce(&mut Self) -> T
     {
         let old = self.restrictions;
         self.restrictions = r;
@@ -3926,7 +3927,9 @@ fn parse_stmt_without_recovery(&mut self) -> PResult<'a, Option<Stmt>> {
             }
         } else {
             // FIXME: Bad copy of attrs
-            match try!(self.parse_item_(attrs.clone(), false, true)) {
+            let restrictions = self.restrictions | Restrictions::NO_NONINLINE_MOD;
+            match try!(self.with_res(restrictions,
+                                     |this| this.parse_item_(attrs.clone(), false, true))) {
                 Some(i) => {
                     let hi = i.span.hi;
                     let decl = P(spanned(lo, hi, DeclKind::Item(i)));
@@ -5257,11 +5260,8 @@ fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo>
             self.push_mod_path(id, outer_attrs);
             try!(self.expect(&token::OpenDelim(token::Brace)));
             let mod_inner_lo = self.span.lo;
-            let old_owns_directory = self.owns_directory;
-            self.owns_directory = true;
             let attrs = try!(self.parse_inner_attributes());
             let m = try!(self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo));
-            self.owns_directory = old_owns_directory;
             self.pop_mod_path();
             Ok((id, ItemKind::Mod(m), Some(attrs)))
         }
@@ -5338,7 +5338,17 @@ fn submod_path(&mut self,
 
         let paths = Parser::default_submod_path(id, &dir_path, self.sess.codemap());
 
-        if !self.owns_directory {
+        if self.restrictions.contains(Restrictions::NO_NONINLINE_MOD) {
+            let msg =
+                "Cannot declare a non-inline module inside a block unless it has a path attribute";
+            let mut err = self.diagnostic().struct_span_err(id_sp, msg);
+            if paths.path_exists {
+                let msg = format!("Maybe `use` the module `{}` instead of redeclaring it",
+                                  paths.name);
+                err.span_note(id_sp, &msg);
+            }
+            return Err(err);
+        } else if !self.owns_directory {
             let mut err = self.diagnostic().struct_span_err(id_sp,
                 "cannot declare a new module at this location");
             let this_module = match self.mod_path_stack.last() {
diff --git a/src/test/compile-fail/cfg-arg-invalid.rs b/src/test/compile-fail/cfg-arg-invalid.rs
new file mode 100644 (file)
index 0000000..4046303
--- /dev/null
@@ -0,0 +1,13 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags: --cfg a{b}
+// error-pattern: invalid --cfg argument: a{b}
+fn main() {}
diff --git a/src/test/compile-fail/non-inline-mod-restriction.rs b/src/test/compile-fail/non-inline-mod-restriction.rs
new file mode 100644 (file)
index 0000000..c4ede12
--- /dev/null
@@ -0,0 +1,15 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Test that non-inline modules are not allowed inside blocks.
+
+fn main() {
+    mod foo; //~ ERROR Cannot declare a non-inline module inside a block
+}
diff --git a/src/test/run-make/llvm-module-pass/Makefile b/src/test/run-make/llvm-module-pass/Makefile
deleted file mode 100644 (file)
index 93c7c4f..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
--include ../tools.mk
-
-# Windows doesn't correctly handle include statements with escaping paths,
-# so this test will not get run on Windows.
-ifdef IS_WINDOWS
-all:
-else
-all: $(call NATIVE_STATICLIB,llvm-pass)
-       $(RUSTC) plugin.rs -C prefer-dynamic
-       $(RUSTC) main.rs
-
-$(TMPDIR)/libllvm-pass.o:
-       $(CXX) $(CFLAGS) $(LLVM_CXXFLAGS) -c llvm-pass.so.cc -o $(TMPDIR)/libllvm-pass.o
-endif
diff --git a/src/test/run-make/llvm-module-pass/llvm-pass.so.cc b/src/test/run-make/llvm-module-pass/llvm-pass.so.cc
deleted file mode 100644 (file)
index 06b0d6c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "llvm/IR/Module.h"
-
-using namespace llvm;
-
-namespace {
-
-  class TestLLVMPass : public ModulePass {
-
-  public:
-
-    static char ID;
-    TestLLVMPass() : ModulePass(ID) { }
-
-    bool runOnModule(Module &M) override;
-
-    const char *getPassName() const override {
-      return "Some LLVM pass";
-    }
-
-  };
-
-}
-
-bool TestLLVMPass::runOnModule(Module &M) {
-  // A couple examples of operations that previously caused segmentation faults
-  // https://github.com/rust-lang/rust/issues/31067
-
-  for (auto F = M.begin(); F != M.end(); ++F) {
-    /* code */
-  }
-
-  LLVMContext &C = M.getContext();
-  IntegerType *Int8Ty  = IntegerType::getInt8Ty(C);
-  PointerType::get(Int8Ty, 0);
-  return true;
-}
-
-char TestLLVMPass::ID = 0;
-
-static RegisterPass<TestLLVMPass> RegisterAFLPass(
-  "some-llvm-pass", "Some LLVM pass");
diff --git a/src/test/run-make/llvm-module-pass/main.rs b/src/test/run-make/llvm-module-pass/main.rs
deleted file mode 100644 (file)
index 5b5ab94..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(plugin)]
-#![plugin(some_plugin)]
-
-fn main() {}
diff --git a/src/test/run-make/llvm-module-pass/plugin.rs b/src/test/run-make/llvm-module-pass/plugin.rs
deleted file mode 100644 (file)
index 039de3c..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![feature(plugin_registrar, rustc_private)]
-#![crate_type = "dylib"]
-#![crate_name = "some_plugin"]
-
-extern crate rustc;
-extern crate rustc_plugin;
-
-#[link(name = "llvm-pass", kind = "static")]
-extern {}
-
-use rustc_plugin::registry::Registry;
-
-#[plugin_registrar]
-pub fn plugin_registrar(reg: &mut Registry) {
-    reg.register_llvm_pass("some-llvm-pass");
-}
diff --git a/src/test/run-make/llvm-pass/Makefile b/src/test/run-make/llvm-pass/Makefile
new file mode 100644 (file)
index 0000000..aab6e89
--- /dev/null
@@ -0,0 +1,17 @@
+-include ../tools.mk
+
+# Windows doesn't correctly handle include statements with escaping paths,
+# so this test will not get run on Windows.
+ifdef IS_WINDOWS
+all:
+else
+all: $(call NATIVE_STATICLIB,llvm-function-pass) $(call NATIVE_STATICLIB,llvm-module-pass)
+       $(RUSTC) plugin.rs -C prefer-dynamic
+       $(RUSTC) main.rs
+
+$(TMPDIR)/libllvm-function-pass.o:
+       $(CXX) $(CFLAGS) $(LLVM_CXXFLAGS) -c llvm-function-pass.so.cc -o $(TMPDIR)/libllvm-function-pass.o
+
+$(TMPDIR)/libllvm-module-pass.o:
+       $(CXX) $(CFLAGS) $(LLVM_CXXFLAGS) -c llvm-module-pass.so.cc -o $(TMPDIR)/libllvm-module-pass.o
+endif
diff --git a/src/test/run-make/llvm-pass/llvm-function-pass.so.cc b/src/test/run-make/llvm-pass/llvm-function-pass.so.cc
new file mode 100644 (file)
index 0000000..4470c40
--- /dev/null
@@ -0,0 +1,56 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "llvm/Pass.h"
+#include "llvm/IR/Function.h"
+
+using namespace llvm;
+
+namespace {
+
+  class TestLLVMPass : public FunctionPass {
+
+  public:
+
+    static char ID;
+    TestLLVMPass() : FunctionPass(ID) { }
+
+    bool runOnFunction(Function &F) override;
+
+    const char *getPassName() const override {
+      return "Some LLVM pass";
+    }
+
+  };
+
+}
+
+bool TestLLVMPass::runOnFunction(Function &F) {
+  // A couple examples of operations that previously caused segmentation faults
+  // https://github.com/rust-lang/rust/issues/31067
+
+  for (auto N = F.begin(); N != F.end(); ++N) {
+    /* code */
+  }
+
+  LLVMContext &C = F.getContext();
+  IntegerType *Int8Ty  = IntegerType::getInt8Ty(C);
+  PointerType::get(Int8Ty, 0);
+  return true;
+}
+
+char TestLLVMPass::ID = 0;
+
+static RegisterPass<TestLLVMPass> RegisterAFLPass(
+  "some-llvm-function-pass", "Some LLVM pass");
diff --git a/src/test/run-make/llvm-pass/llvm-module-pass.so.cc b/src/test/run-make/llvm-pass/llvm-module-pass.so.cc
new file mode 100644 (file)
index 0000000..510375a
--- /dev/null
@@ -0,0 +1,55 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "llvm/IR/Module.h"
+
+using namespace llvm;
+
+namespace {
+
+  class TestLLVMPass : public ModulePass {
+
+  public:
+
+    static char ID;
+    TestLLVMPass() : ModulePass(ID) { }
+
+    bool runOnModule(Module &M) override;
+
+    const char *getPassName() const override {
+      return "Some LLVM pass";
+    }
+
+  };
+
+}
+
+bool TestLLVMPass::runOnModule(Module &M) {
+  // A couple examples of operations that previously caused segmentation faults
+  // https://github.com/rust-lang/rust/issues/31067
+
+  for (auto F = M.begin(); F != M.end(); ++F) {
+    /* code */
+  }
+
+  LLVMContext &C = M.getContext();
+  IntegerType *Int8Ty  = IntegerType::getInt8Ty(C);
+  PointerType::get(Int8Ty, 0);
+  return true;
+}
+
+char TestLLVMPass::ID = 0;
+
+static RegisterPass<TestLLVMPass> RegisterAFLPass(
+  "some-llvm-module-pass", "Some LLVM pass");
diff --git a/src/test/run-make/llvm-pass/main.rs b/src/test/run-make/llvm-pass/main.rs
new file mode 100644 (file)
index 0000000..5b5ab94
--- /dev/null
@@ -0,0 +1,14 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(plugin)]
+#![plugin(some_plugin)]
+
+fn main() {}
diff --git a/src/test/run-make/llvm-pass/plugin.rs b/src/test/run-make/llvm-pass/plugin.rs
new file mode 100644 (file)
index 0000000..f77b2fc
--- /dev/null
@@ -0,0 +1,28 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(plugin_registrar, rustc_private)]
+#![crate_type = "dylib"]
+#![crate_name = "some_plugin"]
+
+extern crate rustc;
+extern crate rustc_plugin;
+
+#[link(name = "llvm-function-pass", kind = "static")]
+#[link(name = "llvm-module-pass", kind = "static")]
+extern {}
+
+use rustc_plugin::registry::Registry;
+
+#[plugin_registrar]
+pub fn plugin_registrar(reg: &mut Registry) {
+    reg.register_llvm_pass("some-llvm-function-pass");
+    reg.register_llvm_pass("some-llvm-module-pass");
+}
diff --git a/src/test/run-pass/issue-29914-2.rs b/src/test/run-pass/issue-29914-2.rs
new file mode 100644 (file)
index 0000000..fe0a6cf
--- /dev/null
@@ -0,0 +1,15 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const ARR: [usize; 5] = [5, 4, 3, 2, 1];
+
+fn main() {
+    assert_eq!(3, ARR[ARR[3]]);
+}
diff --git a/src/test/run-pass/issue-29914-3.rs b/src/test/run-pass/issue-29914-3.rs
new file mode 100644 (file)
index 0000000..3a02764
--- /dev/null
@@ -0,0 +1,16 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+const ARR: [usize; 5] = [5, 4, 3, 2, 1];
+const BLA: usize = ARR[ARR[3]];
+
+fn main() {
+    assert_eq!(3, BLA);
+}
diff --git a/src/test/run-pass/issue-29914.rs b/src/test/run-pass/issue-29914.rs
new file mode 100644 (file)
index 0000000..bb933f0
--- /dev/null
@@ -0,0 +1,16 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+#![feature(const_indexing)]
+
+const ARR: [usize; 5] = [5, 4, 3, 2, 1];
+
+fn main() {
+    assert_eq!(3, ARR[ARR[3]]);
+}