Auto merge of #23593 - Manishearth:rollup, r=Manishearth

(yay, no Saturday)
This commit is contained in:
bors 2015-03-23 00:37:35 +00:00
commit 809a554fca
19 changed files with 347 additions and 205 deletions

View file

@ -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.

View file

@ -1982,7 +1982,7 @@ the namespace hierarchy as it normally would.
## Attributes
```{.ebnf .gram}
attribute : "#!" ? '[' meta_item ']' ;
attribute : '#' '!' ? '[' meta_item ']' ;
meta_item : ident [ '=' literal
| '(' meta_seq ')' ] ? ;
meta_seq : meta_item [ ',' meta_seq ] ? ;
@ -3158,7 +3158,7 @@ ten_times(|j| println!("hello, {}", j));
### While loops
```{.ebnf .gram}
while_expr : "while" no_struct_literal_expr '{' block '}' ;
while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ;
```
A `while` loop begins by evaluating the boolean loop conditional expression.
@ -3223,7 +3223,7 @@ A `continue` expression is only permitted in the body of a loop.
### For expressions
```{.ebnf .gram}
for_expr : "for" pat "in" no_struct_literal_expr '{' block '}' ;
for_expr : [ lifetime ':' ] "for" pat "in" no_struct_literal_expr '{' block '}' ;
```
A `for` expression is a syntactic construct for looping over elements provided

View file

@ -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)

View file

@ -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<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
where K: Borrow<Q>, 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<N> {

128
src/librustc/README.md Normal file
View file

@ -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<T>`, 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.

View file

@ -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<T>`, 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.

View file

@ -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;
}

View file

@ -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| {

View file

@ -1 +1 @@
See the README.txt in ../librustc.
See the README.md in ../librustc.

View file

@ -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
}
}

View file

@ -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)
}
}

View file

@ -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

View file

@ -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<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S>
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<K, V, S, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
where K: Eq + Hash + Borrow<Q>,
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> {

View file

@ -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;

View file

@ -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 <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 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

View file

@ -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 <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 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
_ => ()
};
}

View file

@ -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 <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 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
}

View file

@ -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 <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 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() {}

View file

@ -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 <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(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() {}