CFG_INSTALL_ONLY_RLIB_armv7s-apple-ios = 1
CFG_STATIC_LIB_NAME_armv7s-apple-ios=lib$(1).a
CFG_LIB_DSYM_GLOB_armv7s-apple-ios = lib$(1)-*.a.dSYM
-CFG_JEMALLOC_CFLAGS_armv7s-apple-ios := -arch armv7s -mfpu=vfp4 $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios)
-CFG_GCCISH_CFLAGS_armv7s-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -mfpu=vfp4 -arch armv7s
+CFG_JEMALLOC_CFLAGS_armv7s-apple-ios := -arch armv7s $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios)
+CFG_GCCISH_CFLAGS_armv7s-apple-ios := -Wall -Werror -g -fPIC $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -arch armv7s
CFG_GCCISH_CXXFLAGS_armv7s-apple-ios := -fno-rtti $(CFG_IOS_SDK_FLAGS_armv7s-apple-ios) -I$(CFG_IOS_SDK_armv7s-apple-ios)/usr/include/c++/4.2.1
CFG_GCCISH_LINK_FLAGS_armv7s-apple-ios := -lpthread -syslibroot $(CFG_IOS_SDK_armv7s-apple-ios) -Wl,-no_compact_unwind
CFG_GCCISH_DEF_FLAG_armv7s-apple-ios := -Wl,-exported_symbols_list,
# powerpc64-unknown-linux-gnu configuration
-CROSS_PREFIX_powerpc64-unknown-linux-gnu=powerpc64-linux-gnu-
+CROSS_PREFIX_powerpc64-unknown-linux-gnu=powerpc-linux-gnu-
CC_powerpc64-unknown-linux-gnu=$(CC)
CXX_powerpc64-unknown-linux-gnu=$(CXX)
CPP_powerpc64-unknown-linux-gnu=$(CPP)
`#[doc="..."]` around the body of the comment, i.e., `/// Foo` turns into
`#[doc="Foo"]`.
-Line comments beginning with `//!` and block comments `/*! ... !*/` are
+Line comments beginning with `//!` and block comments `/*! ... */` are
doc comments that apply to the parent of the comment, rather than the item
that follows. That is, they are equivalent to writing `#![doc="..."]` around
the body of the comment. `//!` comments are usually used to document
Cow::Owned(res)
}
- /// Decode a UTF-16 encoded vector `v` into a `String`, returning `None`
+ /// Decode a UTF-16 encoded vector `v` into a `String`, returning `Err`
/// if `v` contains any invalid data.
///
/// # Examples
-Subproject commit af77843345ec6fc7e51113bfd692138d89024bc0
+Subproject commit 91ff43c736de664f8d3cd351e148c09cdea6731e
(the names and divisions are not set in stone and may change;
in general, a finer-grained division of crates is preferable):
-- `libsyntax` contains those things concerned purely with syntax –
+- [`libsyntax`][libsyntax] contains those things concerned purely with syntax –
that is, the AST, parser, pretty-printer, lexer, macro expander, and
utilities for traversing ASTs – are in a separate crate called
"syntax", whose files are in `./../libsyntax`, where `.` is the
passes, such as the type checker, borrow checker, and so forth.
It is the heart of the compiler.
-- `librustc_back` contains some very low-level details that are
+- [`librustc_back`][back] contains some very low-level details that are
specific to different LLVM targets and so forth.
-- `librustc_trans` contains the code to convert from Rust IR into LLVM
+- [`librustc_trans`][trans] contains the code to convert from Rust IR into LLVM
IR, and then from LLVM IR into machine code, as well as the main
driver that orchestrates all the other passes and various other bits
of miscellany. In general it contains code that runs towards the
end of the compilation process.
-- `librustc_driver` invokes the compiler from `libsyntax`, then the
- analysis phases from `librustc`, and finally the lowering and
- codegen passes from `librustc_trans`.
+- [`librustc_driver`][driver] invokes the compiler from
+ [`libsyntax`][libsyntax], then the analysis phases from `librustc`, and
+ finally the lowering and codegen passes from [`librustc_trans`][trans].
Roughly speaking the "order" of the three crates is as follows:
- libsyntax -> librustc -> librustc_trans
- | |
- +-----------------+-------------------+
- |
librustc_driver
+ |
+ +-----------------+-------------------+
+ | |
+ libsyntax -> librustc -> librustc_trans
-Modules in the rustc crate
-==========================
-
-The rustc crate itself consists of the following submodules
+The compiler process:
+=====================
+
+The Rust compiler is comprised of six main compilation phases.
+
+1. Parsing input
+2. Configuration & expanding (cfg rules & syntax extension expansion)
+3. Running analysis passes
+4. Translation to LLVM
+5. LLVM passes
+6. Linking
+
+Phase one is responsible for parsing & lexing the input to the compiler. The
+output of this phase is an abstract syntax tree (AST). The AST at this point
+includes all macro uses & attributes. This means code which will be later
+expanded and/or removed due to `cfg` attributes is still present in this
+version of the AST. Parsing abstracts away details about individual files which
+have been read into the AST.
+
+Phase two handles configuration and macro expansion. You can think of this
+phase as a function acting on the AST from the previous phase. The input for
+this phase is the unexpanded AST from phase one, and the output is an expanded
+version of the same AST. This phase will expand all macros & syntax
+extensions and will evaluate all `cfg` attributes, potentially removing some
+code. The resulting AST will not contain any macros or `macro_use` statements.
+
+The code for these first two phases is in [`libsyntax`][libsyntax].
+
+After this phase, the compiler allocates IDs to each node in the AST
+(technically not every node, but most of them). If we are writing out
+dependencies, that happens now.
+
+The third phase is analysis. This is the most complex phase in the compiler,
+and makes up much of the code. This phase included name resolution, type
+checking, borrow checking, type & lifetime inference, trait selection, method
+selection, linting and so on. Most of the error detection in the compiler comes
+from this phase (with the exception of parse errors which arise during
+parsing). The "output" of this phase is a set of side tables containing
+semantic information about the source program. The analysis code is in
+[`librustc`][rustc] and some other crates with the `librustc_` prefix.
+
+The fourth phase is translation. This phase translates the AST (and the side
+tables from the previous phase) into LLVM IR (intermediate representation).
+This is achieved by calling into the LLVM libraries. The code for this is in
+[`librustc_trans`][trans].
+
+Phase five runs the LLVM backend. This runs LLVM's optimization passes on the
+generated IR and generates machine code resulting in object files. This phase
+is not really part of the Rust compiler, as LLVM carries out all the work.
+The interface between LLVM and Rust is in [`librustc_llvm`][llvm].
+
+The final phase, phase six, links the object files into an executable. This is
+again outsourced to other tools and not performed by the Rust compiler
+directly. The interface is in [`librustc_back`][back] (which also contains some
+things used primarily during translation).
+
+A module called the driver coordinates all these phases. It handles all the
+highest level coordination of compilation from parsing command line arguments
+all the way to invoking the linker to produce an executable.
+
+Modules in the librustc crate
+=============================
+
+The librustc crate itself consists of the following submodules
(mostly, but not entirely, in their own directories):
- session: options and data that pertain to the compilation session as
- util: ubiquitous types and helper functions
- lib: bindings to LLVM
-The entry-point for the compiler is main() in the librustc_driver
+The entry-point for the compiler is main() in the [`librustc_driver`][driver]
crate.
The 3 central data structures:
Each of these is an opaque pointer to an LLVM type,
manipulated through the `lib::llvm` interface.
-
-Control and information flow within the compiler:
--------------------------------------------------
-
-- main() in lib.rs assumes control on startup. Options are
- parsed, platform is detected, etc.
-
-- `./../libsyntax/parse/parser.rs` parses the input files and produces
- an AST that represents the input crate.
-
-- Multiple middle-end passes (`middle/resolve.rs`, `middle/typeck.rs`)
- analyze the semantics of the resulting AST. Each pass generates new
- information about the AST and stores it in various environment data
- structures. The driver passes environments to each compiler pass
- that needs to refer to them.
-
-- Finally, the `trans` module in `librustc_trans` translates the Rust
- AST to LLVM bitcode in a type-directed way. When it's finished
- synthesizing LLVM values, rustc asks LLVM to write them out in some
- form (`.bc`, `.o`) and possibly run the system linker.
+[libsyntax]: https://github.com/rust-lang/rust/tree/master/src/libsyntax/
+[trans]: https://github.com/rust-lang/rust/tree/master/src/librustc_trans/
+[llvm]: https://github.com/rust-lang/rust/tree/master/src/librustc_llvm/
+[back]: https://github.com/rust-lang/rust/tree/master/src/librustc_back/
+[rustc]: https://github.com/rust-lang/rust/tree/master/src/librustc/
+[driver]: https://github.com/rust-lang/rust/tree/master/src/librustc_driver
use self::UseLexicalScopeFlag::*;
use self::ModulePrefixResult::*;
use self::AssocItemResolveResult::*;
-use self::NameSearchType::*;
use self::BareIdentifierPatternResolution::*;
use self::ParentLink::*;
use self::FallbackChecks::*;
ResolveAttempt(Option<PathResolution>),
}
-#[derive(Copy, Clone, PartialEq)]
-enum NameSearchType {
- /// We're doing a name search in order to resolve a `use` directive.
- ImportSearch,
-
- /// We're doing a name search in order to resolve a path type, a path
- /// expression, or a path pattern.
- PathSearch,
-}
-
#[derive(Copy, Clone)]
enum BareIdentifierPatternResolution {
FoundStructOrEnumVariant(Def, LastPrivate),
module_path: &[Name],
index: usize,
span: Span,
- name_search_type: NameSearchType,
lp: LastPrivate)
-> ResolveResult<(Module<'a>, LastPrivate)> {
fn search_parent_externals<'a>(needle: Name, module: Module<'a>)
// modules as we go.
while index < module_path_len {
let name = module_path[index];
- match self.resolve_name_in_module(search_module,
- name,
- TypeNS,
- name_search_type,
- false) {
+ match self.resolve_name_in_module(search_module, name, TypeNS, false) {
Failed(None) => {
let segment_name = name.as_str();
let module_name = module_to_string(search_module);
module_: Module<'a>,
module_path: &[Name],
use_lexical_scope: UseLexicalScopeFlag,
- span: Span,
- name_search_type: NameSearchType)
+ span: Span)
-> ResolveResult<(Module<'a>, LastPrivate)> {
let module_path_len = module_path.len();
assert!(module_path_len > 0);
module_path,
start_index,
span,
- name_search_type,
last_private)
}
}
// Resolve the name in the parent module.
- match self.resolve_name_in_module(search_module,
- name,
- namespace,
- PathSearch,
- true) {
+ match self.resolve_name_in_module(search_module, name, namespace, true) {
Failed(Some((span, msg))) => {
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
}
module_: Module<'a>,
name: Name,
namespace: Namespace,
- name_search_type: NameSearchType,
allow_private_imports: bool)
-> ResolveResult<(Target<'a>, bool)> {
debug!("(resolving name in module) resolving `{}` in `{}`",
}
}
- // Next, check the module's imports if necessary.
-
- // If this is a search of all imports, we should be done with glob
- // resolution at this point.
- if name_search_type == PathSearch {
- assert_eq!(module_.glob_count.get(), 0);
- }
-
// Check the list of resolved imports.
let children = module_.import_resolutions.borrow();
match children.get(&name) {
self.value_ribs.push(Rib::new(NormalRibKind));
}
- // Check for imports appearing after non-item statements.
- let mut found_non_item = false;
- for statement in &block.stmts {
- if let hir::StmtDecl(ref declaration, _) = statement.node {
- if let hir::DeclItem(i) = declaration.node {
- let i = self.ast_map.expect_item(i.id);
- match i.node {
- ItemExternCrate(_) | ItemUse(_) if found_non_item => {
- span_err!(self.session,
- i.span,
- E0154,
- "imports are not allowed after non-item statements");
- }
- _ => {}
- }
- } else {
- found_non_item = true
- }
- } else {
- found_non_item = true;
- }
- }
-
// Descend into the block.
intravisit::walk_block(self, block);
}
}
- Indeterminate => {
- panic!("unexpected indeterminate result");
- }
+ Indeterminate => return BareIdentifierPatternUnresolved,
Failed(err) => {
match err {
Some((span, msg)) => {
let containing_module;
let last_private;
let current_module = self.current_module;
- match self.resolve_module_path(current_module,
- &module_path[..],
- UseLexicalScope,
- span,
- PathSearch) {
+ match self.resolve_module_path(current_module, &module_path, UseLexicalScope, span) {
Failed(err) => {
let (span, msg) = match err {
Some((span, msg)) => (span, msg),
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
return None;
}
- Indeterminate => panic!("indeterminate unexpected"),
+ Indeterminate => return None,
Success((resulting_module, resulting_last_private)) => {
containing_module = resulting_module;
last_private = resulting_last_private;
}
let name = segments.last().unwrap().identifier.name;
- let def = match self.resolve_name_in_module(containing_module,
- name,
- namespace,
- NameSearchType::PathSearch,
- false) {
+ let def = match self.resolve_name_in_module(containing_module, name, namespace, false) {
Success((Target { binding, .. }, _)) => {
let (def, lp) = binding.def_and_lp();
(def, last_private.or(lp))
&module_path[..],
0,
span,
- PathSearch,
LastMod(AllPublic)) {
Failed(err) => {
let (span, msg) = match err {
return None;
}
- Indeterminate => {
- panic!("indeterminate unexpected");
- }
+ Indeterminate => return None,
Success((resulting_module, resulting_last_private)) => {
containing_module = resulting_module;
}
let name = segments.last().unwrap().identifier.name;
- match self.resolve_name_in_module(containing_module,
- name,
- namespace,
- NameSearchType::PathSearch,
- false) {
+ match self.resolve_name_in_module(containing_module, name, namespace, false) {
Success((Target { binding, .. }, _)) => {
let (def, lp) = binding.def_and_lp();
Some((def, last_private.or(lp)))
if let Success((target, _)) = self.resolve_name_in_module(module,
ident.unhygienic_name,
namespace,
- PathSearch,
true) {
if let Some(def) = target.binding.def() {
return Some(LocalDef::from_def(def));
}
}
}
- Indeterminate => {
- panic!("unexpected indeterminate result");
- }
+ Indeterminate => None,
Failed(err) => {
debug!("(resolving item path by identifier in lexical scope) failed to resolve {}",
name);
}
}
} else {
- match this.resolve_module_path(root,
- &name_path[..],
- UseLexicalScope,
- span,
- PathSearch) {
+ match this.resolve_module_path(root, &name_path, UseLexicalScope, span) {
Success((module, _)) => Some(module),
_ => None,
}
let current_module = self.current_module;
match self.resolve_module_path(current_module,
- &name_path[..],
- UseLexicalScope,
- expr.span,
- PathSearch) {
+ &name_path[..],
+ UseLexicalScope,
+ expr.span) {
Success(_) => {
context = UnresolvedNameContext::PathIsMod(expr.id);
},
use {NameBindings, NameBinding};
use NamespaceResult::{BoundResult, UnboundResult, UnknownResult};
use NamespaceResult;
-use NameSearchType;
use ResolveResult;
use Resolver;
use UseLexicalScopeFlag;
match self.resolver.resolve_module_path(module_,
&module_path[..],
UseLexicalScopeFlag::DontUseLexicalScope,
- import_directive.span,
- NameSearchType::ImportSearch) {
+ import_directive.span) {
ResolveResult::Failed(err) => {
resolution_result = ResolveResult::Failed(err);
None
[] => primitive_link(f, clean::PrimitiveTuple, "()"),
[ref one] => {
try!(primitive_link(f, clean::PrimitiveTuple, "("));
- try!(write!(f, "{}", one));
+ try!(write!(f, "{},", one));
primitive_link(f, clean::PrimitiveTuple, ")")
}
many => {
#[cfg(not(target_env = "newlib"))]
use ffi::CString;
use io;
-use libc::PTHREAD_STACK_MIN;
use libc;
use mem;
use ptr;
});
match unsafe { __pthread_get_minstack } {
- None => PTHREAD_STACK_MIN as usize,
+ None => libc::PTHREAD_STACK_MIN as usize,
Some(f) => unsafe { f(attr) as usize },
}
}
// No point in looking up __pthread_get_minstack() on non-glibc
// platforms.
-#[cfg(not(target_os = "linux"))]
+#[cfg(all(not(target_os = "linux"),
+ not(target_os = "netbsd")))]
+fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
+ libc::PTHREAD_STACK_MIN as usize
+}
+
+#[cfg(target_os = "netbsd")]
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
- PTHREAD_STACK_MIN as usize
+ 2048 // just a guess
}
};
// Output error metadata to `tmp/extended-errors/<target arch>/<crate name>.json`
- let target_triple = env::var("CFG_COMPILER_HOST_TRIPLE")
- .ok().expect("unable to determine target arch from $CFG_COMPILER_HOST_TRIPLE");
-
- with_registered_diagnostics(|diagnostics| {
- if let Err(e) = output_metadata(ecx,
- &target_triple,
- &crate_name.name.as_str(),
- &diagnostics) {
- ecx.span_bug(span, &format!(
- "error writing metadata for triple `{}` and crate `{}`, error: {}, cause: {:?}",
- target_triple, crate_name, e.description(), e.cause()
- ));
- }
- });
+ if let Ok(target_triple) = env::var("CFG_COMPILER_HOST_TRIPLE") {
+ with_registered_diagnostics(|diagnostics| {
+ if let Err(e) = output_metadata(ecx,
+ &target_triple,
+ &crate_name.name.as_str(),
+ &diagnostics) {
+ ecx.span_bug(span, &format!(
+ "error writing metadata for triple `{}` and crate `{}`, error: {}, \
+ cause: {:?}",
+ target_triple, crate_name, e.description(), e.cause()
+ ));
+ }
+ });
+ } else {
+ ecx.span_err(span, &format!(
+ "failed to write metadata for crate `{}` because $CFG_COMPILER_HOST_TRIPLE is not set",
+ crate_name));
+ }
// Construct the output expression.
let (count, expr) =
let bar = 5;
//~^ ERROR declaration of `bar` shadows an enum variant or unit-like struct in scope
use foo::bar;
- //~^ ERROR imports are not allowed after non-item statements
}
+++ /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.
-
-mod bar {
- pub fn foo() -> bool { true }
-}
-
-fn main() {
- let foo = || false;
- use bar::foo;
- //~^ ERROR imports are not allowed after non-item statements
- assert_eq!(foo(), false);
-}
--- /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.
+
+// This checks that a path that cannot be resolved because of an indeterminate import
+// does not trigger an ICE.
+
+mod foo {
+ pub use self::*; //~ ERROR unresolved
+}
+
+fn main() {
+ foo::f(); //~ ERROR unresolved
+}
--- /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.
+
+mod bar {
+ pub fn foo() -> bool { true }
+}
+
+fn main() {
+ let foo = || false;
+ use bar::foo;
+ assert_eq!(foo(), false);
+}
panic!();
} else {
- let test = std::process::Command::new(&args[0]).arg("run_test").output().unwrap();
+ let test = std::process::Command::new(&args[0]).arg("run_test")
+ .env_remove("RUST_BACKTRACE")
+ .output()
+ .unwrap();
assert!(!test.status.success());
let err = String::from_utf8_lossy(&test.stderr);
let mut it = err.lines();
--- /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.
+
+#![crate_name = "foo"]
+
+// @has foo/fn.tuple0.html //pre 'pub fn tuple0(x: ())'
+pub fn tuple0(x: ()) -> () { x }
+// @has foo/fn.tuple1.html //pre 'pub fn tuple1(x: (i32,)) -> (i32,)'
+pub fn tuple1(x: (i32,)) -> (i32,) { x }
+// @has foo/fn.tuple2.html //pre 'pub fn tuple2(x: (i32, i32)) -> (i32, i32)'
+pub fn tuple2(x: (i32, i32)) -> (i32, i32) { x }