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
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
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
doc \
driver \
etc \
- error-index-generator \
+ error_index_generator \
$(foreach crate,$(CRATES),lib$(crate)) \
libcollectionstest \
libcoretest \
# ./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
# 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)
endef
-PREPARE_TOOLS = $(filter-out compiletest rustbook error-index-generator, $(TOOLS))
+PREPARE_TOOLS = $(filter-out compiletest rustbook error_index_generator, $(TOOLS))
# $(1) is tool
$(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
```
(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:
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:
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
+++ /dev/null
-// 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());
- }
-}
--- /dev/null
+// 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());
+ }
+}
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)
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):
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):
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
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
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))
// 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).
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
///
#![stable(feature = "rust1", since = "1.0.0")]
-uint_module! { u16, i16, 16 }
+uint_module! { u16, 16 }
#![stable(feature = "rust1", since = "1.0.0")]
-uint_module! { u32, i32, 32 }
+uint_module! { u32, 32 }
#![stable(feature = "rust1", since = "1.0.0")]
-uint_module! { u64, i64, 64 }
+uint_module! { u64, 64 }
#![stable(feature = "rust1", since = "1.0.0")]
-uint_module! { u8, i8, 8 }
+uint_module! { u8, 8 }
#![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",
#![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 }
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;
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,
// 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>()
}
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 { }
$(
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};
PpmSource(PpSourceMode),
PpmHir(PpSourceMode),
PpmFlowGraph(PpFlowGraphMode),
+ PpmMir,
}
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),
_ => {
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`, \
PpmSource(PpmExpandedIdentified) |
PpmSource(PpmExpandedHygiene) |
PpmHir(_) |
+ PpmMir |
PpmFlowGraph(_) => true,
PpmSource(PpmTyped) => panic!("invalid state"),
}
PpmSource(PpmExpandedIdentified) |
PpmSource(PpmExpandedHygiene) |
PpmHir(_) |
+ PpmMir |
PpmFlowGraph(_) => true,
PpmSource(PpmTyped) => panic!("invalid state"),
}
})
}
+ (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(|| {
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};
}
}
-#[derive(Copy, Clone)]
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum TrueConst {
Yes, No
}
},
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)),
<p>
Search functions by type signature (e.g.
- <code>vec -> usize</code>)
+ <code>vec -> usize</code> or <code>* -> vec</code>)
</p>
</div>
</div>
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});
}
}
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);
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
};
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() {
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);
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(())
}
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)
}
#[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,
}
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
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() {
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
}
}
flags Restrictions: u8 {
const RESTRICTION_STMT_EXPR = 1 << 0,
const RESTRICTION_NO_STRUCT_LITERAL = 1 << 1,
+ const NO_NONINLINE_MOD = 1 << 2,
}
}
/// 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;
}
} 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)));
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)))
}
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() {
--- /dev/null
+// 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() {}
--- /dev/null
+// 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
+}
+++ /dev/null
--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
+++ /dev/null
-// 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");
+++ /dev/null
-// 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() {}
+++ /dev/null
-// 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");
-}
--- /dev/null
+-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
--- /dev/null
+// 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");
--- /dev/null
+// 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");
--- /dev/null
+// 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() {}
--- /dev/null
+// 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");
+}
--- /dev/null
+// 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]]);
+}
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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]]);
+}