diff --git a/man/rustc.1 b/man/rustc.1 index 33ef3f9ee4ac..b15829db431d 100644 --- a/man/rustc.1 +++ b/man/rustc.1 @@ -242,7 +242,7 @@ full debug info with variable and type information. \fBopt\-level\fR=\fIVAL\fR Optimize with possible levels 0\[en]3 -.SH ENVIRONMENT VARIABLES +.SH ENVIRONMENT Some of these affect the output of the compiler, while others affect programs which link to the standard library. diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md index 6ff51e8d1b92..76f8b6c97381 100644 --- a/src/doc/trpl/SUMMARY.md +++ b/src/doc/trpl/SUMMARY.md @@ -1,6 +1,6 @@ # Summary -* [I: The Basics](basic.md) +* [The Basics](basic.md) * [Installing Rust](installing-rust.md) * [Hello, world!](hello-world.md) * [Hello, Cargo!](hello-cargo.md) @@ -14,7 +14,7 @@ * [Strings](strings.md) * [Arrays, Vectors, and Slices](arrays-vectors-and-slices.md) * [Standard Input](standard-input.md) -* [II: Intermediate Rust](intermediate.md) +* [Intermediate Rust](intermediate.md) * [Crates and Modules](crates-and-modules.md) * [Testing](testing.md) * [Pointers](pointers.md) @@ -31,7 +31,7 @@ * [Concurrency](concurrency.md) * [Error Handling](error-handling.md) * [Documentation](documentation.md) -* [III: Advanced Topics](advanced.md) +* [Advanced Topics](advanced.md) * [FFI](ffi.md) * [Unsafe Code](unsafe.md) * [Advanced Macros](advanced-macros.md) diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index c7e1e3c91766..a9e1ce8d7ce5 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -24,7 +24,7 @@ use core::default::Default; use core::fmt::Debug; use core::hash::{Hash, Hasher}; use core::iter::{Map, FromIterator, IntoIterator}; -use core::ops::{Index, IndexMut}; +use core::ops::{Index}; use core::{iter, fmt, mem, usize}; use Bound::{self, Included, Excluded, Unbounded}; @@ -925,15 +925,6 @@ impl Index for BTreeMap } } -#[stable(feature = "rust1", since = "1.0.0")] -impl IndexMut for BTreeMap - where K: Borrow, Q: Ord -{ - fn index_mut(&mut self, key: &Q) -> &mut V { - self.get_mut(key).expect("no entry found for key") - } -} - /// Genericises over how to get the correct type of iterator from the correct type /// of Node ownership. trait Traverse { diff --git a/src/librustc/README.md b/src/librustc/README.md new file mode 100644 index 000000000000..31812e19aee8 --- /dev/null +++ b/src/librustc/README.md @@ -0,0 +1,128 @@ +An informal guide to reading and working on the rustc compiler. +================================================================== + +If you wish to expand on this document, or have a more experienced +Rust contributor add anything else to it, please get in touch: + +* http://internals.rust-lang.org/ +* https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust + +or file a bug: + +https://github.com/rust-lang/rust/issues + +Your concerns are probably the same as someone else's. + +The crates of rustc +=================== + +Rustc consists of a number of crates, including `libsyntax`, +`librustc`, `librustc_back`, `librustc_trans`, and `librustc_driver` +(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 – + 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 + current directory (that is, the parent directory of front/, middle/, + back/, and so on). + +- `librustc` (the current directory) contains the high-level analysis + 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 + specific to different LLVM targets and so forth. + +- `librustc_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`. + +Roughly speaking the "order" of the three crates is as follows: + + libsyntax -> librustc -> librustc_trans + | | + +-----------------+-------------------+ + | + librustc_driver + + +Modules in the rustc crate +========================== + +The rustc 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 + a whole +- middle: middle-end: name resolution, typechecking, LLVM code + generation +- metadata: encoder and decoder for data required by separate + compilation +- plugin: infrastructure for compiler plugins +- lint: infrastructure for compiler warnings +- util: ubiquitous types and helper functions +- lib: bindings to LLVM + +The entry-point for the compiler is main() in the librustc_trans +crate. + +The 3 central data structures: +------------------------------ + +1. `./../libsyntax/ast.rs` defines the AST. The AST is treated as + immutable after parsing, but it depends on mutable context data + structures (mainly hash maps) to give it meaning. + + - Many – though not all – nodes within this data structure are + wrapped in the type `spanned`, meaning that the front-end has + marked the input coordinates of that node. The member `node` is + the data itself, the member `span` is the input location (file, + line, column; both low and high). + + - Many other nodes within this data structure carry a + `def_id`. These nodes represent the 'target' of some name + reference elsewhere in the tree. When the AST is resolved, by + `middle/resolve.rs`, all names wind up acquiring a def that they + point to. So anything that can be pointed-to by a name winds + up with a `def_id`. + +2. `middle/ty.rs` defines the datatype `sty`. This is the type that + represents types after they have been resolved and normalized by + the middle-end. The typeck phase converts every ast type to a + `ty::sty`, and the latter is used to drive later phases of + compilation. Most variants in the `ast::ty` tag have a + corresponding variant in the `ty::sty` tag. + +3. `./../librustc_llvm/lib.rs` defines the exported types + `ValueRef`, `TypeRef`, `BasicBlockRef`, and several others. + 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. diff --git a/src/librustc/README.txt b/src/librustc/README.txt deleted file mode 100644 index 9b364768208e..000000000000 --- a/src/librustc/README.txt +++ /dev/null @@ -1,124 +0,0 @@ -An informal guide to reading and working on the rustc compiler. -================================================================== - -If you wish to expand on this document, or have a more experienced -Rust contributor add anything else to it, please get in touch: - -* http://internals.rust-lang.org/ -* https://chat.mibbit.com/?server=irc.mozilla.org&channel=%23rust - -or file a bug: - -https://github.com/rust-lang/rust/issues - -Your concerns are probably the same as someone else's. - -The crates of rustc -=================== - -Rustc consists of four crates altogether: `libsyntax`, `librustc`, -`librustc_back`, and `librustc_trans` (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 -- - 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 current - directory (that is, the parent directory of front/, middle/, back/, - and so on). - -- `librustc` (the current directory) contains the high-level analysis - 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 - specific to different LLVM targets and so forth. - -- `librustc_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. - -Roughly speaking the "order" of the three crates is as follows: - - libsyntax -> librustc -> librustc_trans - | | - +-----------------+-------------------+ - | - librustc_trans/driver - -Here the role of `librustc_trans/driver` is to invoke the compiler -from libsyntax, then the analysis phases from librustc, and finally -the lowering and codegen passes from librustc_trans. - -Modules in the rustc crate -========================== - -The rustc crate itself consists of the following subdirectories -(mostly, but not entirely, in their own directories): - -session - options and data that pertain to the compilation session as a whole -middle - middle-end: name resolution, typechecking, LLVM code - generation -metadata - encoder and decoder for data required by - separate compilation -util - ubiquitous types and helper functions -lib - bindings to LLVM - -The entry-point for the compiler is main() in the librustc_trans -crate. - -The 3 central data structures: ------------------------------- - -#1: ./../libsyntax/ast.rs defines the AST. The AST is treated as immutable - after parsing, but it depends on mutable context data structures - (mainly hash maps) to give it meaning. - - - Many -- though not all -- nodes within this data structure are - wrapped in the type `spanned`, meaning that the front-end has - marked the input coordinates of that node. The member .node is - the data itself, the member .span is the input location (file, - line, column; both low and high). - - - Many other nodes within this data structure carry a - def_id. These nodes represent the 'target' of some name - reference elsewhere in the tree. When the AST is resolved, by - middle/resolve.rs, all names wind up acquiring a def that they - point to. So anything that can be pointed-to by a name winds - up with a def_id. - -#2: middle/ty.rs defines the datatype sty. This is the type that - represents types after they have been resolved and normalized by - the middle-end. The typeck phase converts every ast type to a - ty::sty, and the latter is used to drive later phases of - compilation. Most variants in the ast::ty tag have a - corresponding variant in the ty::sty tag. - -#3: lib/llvm.rs (in librustc_trans) defines the exported types - ValueRef, TypeRef, BasicBlockRef, and several others. 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. diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b619c6a77d00..566af2590e6c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -900,7 +900,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { return; } if self.glob_map.contains_key(&import_id) { - self.glob_map[import_id].insert(name); + self.glob_map.get_mut(&import_id).unwrap().insert(name); return; } diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 737ec71cab3d..46451019760d 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -603,7 +603,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { // We've successfully resolved the import. Write the results in. let mut import_resolutions = module_.import_resolutions.borrow_mut(); - let import_resolution = &mut (*import_resolutions)[target]; + let import_resolution = import_resolutions.get_mut(&target).unwrap(); { let mut check_and_write_import = |namespace, result: &_, used_public: &mut bool| { diff --git a/src/librustc_trans/README.txt b/src/librustc_trans/README.txt index 3904db4433c8..1f416d5404d2 100644 --- a/src/librustc_trans/README.txt +++ b/src/librustc_trans/README.txt @@ -1 +1 @@ -See the README.txt in ../librustc. +See the README.md in ../librustc. diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index f584de7c47f3..ebd92faaf0f5 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -983,56 +983,72 @@ pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>, /// gives us better information about what we are loading. pub fn load_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, ptr: ValueRef, t: Ty<'tcx>) -> ValueRef { - if type_is_zero_size(cx.ccx(), t) { - C_undef(type_of::type_of(cx.ccx(), t)) - } else if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() { - // We want to pass small aggregates as immediate values, but using an aggregate LLVM type - // for this leads to bad optimizations, so its arg type is an appropriately sized integer - // and we have to convert it - Load(cx, BitCast(cx, ptr, type_of::arg_type_of(cx.ccx(), t).ptr_to())) - } else { - unsafe { - let global = llvm::LLVMIsAGlobalVariable(ptr); - if !global.is_null() && llvm::LLVMIsGlobalConstant(global) == llvm::True { - let val = llvm::LLVMGetInitializer(global); - if !val.is_null() { - // This could go into its own function, for DRY. - // (something like "pre-store packing/post-load unpacking") - if ty::type_is_bool(t) { - return Trunc(cx, val, Type::i1(cx.ccx())); - } else { - return val; - } - } + if cx.unreachable.get() || type_is_zero_size(cx.ccx(), t) { + return C_undef(type_of::type_of(cx.ccx(), t)); + } + + let ptr = to_arg_ty_ptr(cx, ptr, t); + + if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() { + return Load(cx, ptr); + } + + unsafe { + let global = llvm::LLVMIsAGlobalVariable(ptr); + if !global.is_null() && llvm::LLVMIsGlobalConstant(global) == llvm::True { + let val = llvm::LLVMGetInitializer(global); + if !val.is_null() { + return from_arg_ty(cx, val, t); } } - if ty::type_is_bool(t) { - Trunc(cx, LoadRangeAssert(cx, ptr, 0, 2, llvm::False), Type::i1(cx.ccx())) - } else if ty::type_is_char(t) { - // a char is a Unicode codepoint, and so takes values from 0 - // to 0x10FFFF inclusive only. - LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False) - } else if (ty::type_is_region_ptr(t) || ty::type_is_unique(t)) - && !common::type_is_fat_ptr(cx.tcx(), t) { - LoadNonNull(cx, ptr) - } else { - Load(cx, ptr) - } } + + let val = if ty::type_is_bool(t) { + LoadRangeAssert(cx, ptr, 0, 2, llvm::False) + } else if ty::type_is_char(t) { + // a char is a Unicode codepoint, and so takes values from 0 + // to 0x10FFFF inclusive only. + LoadRangeAssert(cx, ptr, 0, 0x10FFFF + 1, llvm::False) + } else if (ty::type_is_region_ptr(t) || ty::type_is_unique(t)) + && !common::type_is_fat_ptr(cx.tcx(), t) { + LoadNonNull(cx, ptr) + } else { + Load(cx, ptr) + }; + + from_arg_ty(cx, val, t) } /// Helper for storing values in memory. Does the necessary conversion if the in-memory type /// differs from the type used for SSA values. pub fn store_ty<'blk, 'tcx>(cx: Block<'blk, 'tcx>, v: ValueRef, dst: ValueRef, t: Ty<'tcx>) { - if ty::type_is_bool(t) { - Store(cx, ZExt(cx, v, Type::i8(cx.ccx())), dst); - } else if type_is_immediate(cx.ccx(), t) && type_of::type_of(cx.ccx(), t).is_aggregate() { + Store(cx, to_arg_ty(cx, v, t), to_arg_ty_ptr(cx, dst, t)); +} + +pub fn to_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef { + if ty::type_is_bool(ty) { + ZExt(bcx, val, Type::i8(bcx.ccx())) + } else { + val + } +} + +pub fn from_arg_ty(bcx: Block, val: ValueRef, ty: Ty) -> ValueRef { + if ty::type_is_bool(ty) { + Trunc(bcx, val, Type::i1(bcx.ccx())) + } else { + val + } +} + +pub fn to_arg_ty_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ptr: ValueRef, ty: Ty<'tcx>) -> ValueRef { + if type_is_immediate(bcx.ccx(), ty) && type_of::type_of(bcx.ccx(), ty).is_aggregate() { // We want to pass small aggregates as immediate values, but using an aggregate LLVM type // for this leads to bad optimizations, so its arg type is an appropriately sized integer // and we have to convert it - Store(cx, v, BitCast(cx, dst, type_of::arg_type_of(cx.ccx(), t).ptr_to())); + BitCast(bcx, ptr, type_of::arg_type_of(bcx.ccx(), ty).ptr_to()) } else { - Store(cx, v, dst); + ptr } } diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index 69ca9a5e81cb..d158cfa7b887 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -446,10 +446,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, call_debug_location) } (_, "volatile_load") => { - VolatileLoad(bcx, llargs[0]) + let tp_ty = *substs.types.get(FnSpace, 0); + let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty); + from_arg_ty(bcx, VolatileLoad(bcx, ptr), tp_ty) }, (_, "volatile_store") => { - VolatileStore(bcx, llargs[1], llargs[0]); + let tp_ty = *substs.types.get(FnSpace, 0); + let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty); + let val = to_arg_ty(bcx, llargs[1], tp_ty); + VolatileStore(bcx, val, ptr); C_nil(ccx) }, @@ -709,8 +714,11 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, llvm::SequentiallyConsistent }; - let res = AtomicCmpXchg(bcx, llargs[0], llargs[1], - llargs[2], order, + let tp_ty = *substs.types.get(FnSpace, 0); + let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty); + let cmp = to_arg_ty(bcx, llargs[1], tp_ty); + let src = to_arg_ty(bcx, llargs[2], tp_ty); + let res = AtomicCmpXchg(bcx, ptr, cmp, src, order, strongest_failure_ordering); if unsafe { llvm::LLVMVersionMinor() >= 5 } { ExtractValue(bcx, res, 0) @@ -720,10 +728,15 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, } "load" => { - AtomicLoad(bcx, llargs[0], order) + let tp_ty = *substs.types.get(FnSpace, 0); + let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty); + from_arg_ty(bcx, AtomicLoad(bcx, ptr, order), tp_ty) } "store" => { - AtomicStore(bcx, llargs[1], llargs[0], order); + let tp_ty = *substs.types.get(FnSpace, 0); + let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty); + let val = to_arg_ty(bcx, llargs[1], tp_ty); + AtomicStore(bcx, val, ptr, order); C_nil(ccx) } @@ -749,7 +762,10 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, _ => ccx.sess().fatal("unknown atomic operation") }; - AtomicRMW(bcx, atom_op, llargs[0], llargs[1], order) + let tp_ty = *substs.types.get(FnSpace, 0); + let ptr = to_arg_ty_ptr(bcx, llargs[0], tp_ty); + let val = to_arg_ty(bcx, llargs[1], tp_ty); + AtomicRMW(bcx, atom_op, ptr, val, order) } } diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index 09592db8a116..ce4bb4465517 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -380,7 +380,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> { // borrow_kind of the upvar to make sure it // is inferred to mutable if necessary let mut upvar_capture_map = self.fcx.inh.upvar_capture_map.borrow_mut(); - let ub = &mut upvar_capture_map[upvar_id]; + let ub = upvar_capture_map.get_mut(&upvar_id).unwrap(); self.adjust_upvar_borrow_kind(upvar_id, ub, borrow_kind); // also need to be in an FnMut closure since this is not an ImmBorrow diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 60b1738d2c98..9139e182ce47 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -23,7 +23,7 @@ use hash::{Hash, SipHasher}; use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map}; use marker::Sized; use mem::{self, replace}; -use ops::{Deref, FnMut, Index, IndexMut}; +use ops::{Deref, FnMut, Index}; use option::Option::{self, Some, None}; use rand::{self, Rng}; use result::Result::{self, Ok, Err}; @@ -1258,18 +1258,6 @@ impl Index for HashMap } } -#[stable(feature = "rust1", since = "1.0.0")] -impl IndexMut for HashMap - where K: Eq + Hash + Borrow, - Q: Eq + Hash, - S: HashState, -{ - #[inline] - fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V { - self.get_mut(index).expect("no entry found for key") - } -} - /// HashMap iterator. #[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, K: 'a, V: 'a> { diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 1cbfbbf29278..130fd1d7dc83 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -40,7 +40,7 @@ use fmt; /// among threads to ensure that a possibly invalid invariant is not witnessed. /// /// A poisoned mutex, however, does not prevent all access to the underlying -/// data. The `PoisonError` type has an `into_guard` method which will return +/// data. The `PoisonError` type has an `into_inner` method which will return /// the guard that would have otherwise been returned on a successful lock. This /// allows access to the data, despite the lock being poisoned. /// @@ -105,7 +105,7 @@ use fmt; /// // pattern matched on to return the underlying guard on both branches. /// let mut guard = match lock.lock() { /// Ok(guard) => guard, -/// Err(poisoned) => poisoned.into_guard(), +/// Err(poisoned) => poisoned.into_inner(), /// }; /// /// *guard += 1; diff --git a/src/test/compile-fail-fulldeps/gated-macro-reexports.rs b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs new file mode 100644 index 000000000000..a88445bafc04 --- /dev/null +++ b/src/test/compile-fail-fulldeps/gated-macro-reexports.rs @@ -0,0 +1,22 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that macro reexports item are gated by `macro_reexport` feature gate. + +// aux-build:macro_reexport_1.rs +// ignore-stage1 + +#![crate_type = "dylib"] + +#[macro_reexport(reexported)] +#[macro_use] #[no_link] +extern crate macro_reexport_1; +//~^ ERROR macros reexports are experimental and possibly buggy +//~| HELP add #![feature(macro_reexport)] to the crate attributes to enable diff --git a/src/test/compile-fail/gated-box-patterns.rs b/src/test/compile-fail/gated-box-patterns.rs new file mode 100644 index 000000000000..abaa256d52e7 --- /dev/null +++ b/src/test/compile-fail/gated-box-patterns.rs @@ -0,0 +1,22 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that patterns including the box syntax are gated by `box_patterns` feature gate. + +fn main() { + let x = Box::new(1); + + match x { + box 1 => (), + //~^ box pattern syntax is experimental + //~| add #![feature(box_patterns)] to the crate attributes to enable + _ => () + }; +} diff --git a/src/test/compile-fail/gated-box-syntax.rs b/src/test/compile-fail/gated-box-syntax.rs new file mode 100644 index 000000000000..3e08c1f7a713 --- /dev/null +++ b/src/test/compile-fail/gated-box-syntax.rs @@ -0,0 +1,17 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the use of the box syntax is gated by `box_syntax` feature gate. + +fn main() { + let x = box 3; + //~^ ERROR box expression syntax is experimental; you can call `Box::new` instead. + //~| HELP add #![feature(box_syntax)] to the crate attributes to enable +} diff --git a/src/test/compile-fail/gated-simd-ffi.rs b/src/test/compile-fail/gated-simd-ffi.rs new file mode 100644 index 000000000000..c0a251e77a31 --- /dev/null +++ b/src/test/compile-fail/gated-simd-ffi.rs @@ -0,0 +1,27 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that the use of smid types in the ffi is gated by `smid_ffi` feature gate. + +#![feature(simd)] + +#[repr(C)] +#[derive(Copy)] +#[simd] +pub struct f32x4(f32, f32, f32, f32); + +#[allow(dead_code)] +extern { + fn foo(x: f32x4); + //~^ ERROR use of SIMD type `f32x4` in FFI is highly experimental and may result in invalid code + //~| HELP add #![feature(simd_ffi)] to the crate attributes to enable +} + +fn main() {} diff --git a/src/test/run-pass/issue-23550.rs b/src/test/run-pass/issue-23550.rs new file mode 100644 index 000000000000..97357c1dba46 --- /dev/null +++ b/src/test/run-pass/issue-23550.rs @@ -0,0 +1,39 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(core)] +#![allow(warnings)] + +use std::intrinsics; + +#[derive(Copy)] +struct Wrap(i64); + +// These volatile and atomic intrinsics used to cause an ICE + +unsafe fn test_bool(p: &mut bool, v: bool) { + intrinsics::volatile_load(p); + intrinsics::volatile_store(p, v); + intrinsics::atomic_load(p); + intrinsics::atomic_cxchg(p, v, v); + intrinsics::atomic_store(p, v); + intrinsics::atomic_xchg(p, v); +} + +unsafe fn test_immediate_fca(p: &mut Wrap, v: Wrap) { + intrinsics::volatile_load(p); + intrinsics::volatile_store(p, v); + intrinsics::atomic_load(p); + intrinsics::atomic_cxchg(p, v, v); + intrinsics::atomic_store(p, v); + intrinsics::atomic_xchg(p, v); +} + +fn main() {}