auto merge of #17343 : alexcrichton/rust/rollup, r=alexcrichton

This commit is contained in:
bors 2014-09-17 18:26:14 +00:00
commit b88d1030e1
63 changed files with 560 additions and 346 deletions

21
configure vendored
View File

@ -453,6 +453,8 @@ valopt datadir "${CFG_PREFIX}/share" "install data"
valopt infodir "${CFG_PREFIX}/share/info" "install additional info"
valopt mandir "${CFG_PREFIX}/share/man" "install man pages in PATH"
valopt release-channel "source" "the name of the release channel to build"
# On windows we just store the libraries in the bin directory because
# there's no rpath. This is where the build system itself puts libraries;
# --libdir is used to configure the installation directory.
@ -481,6 +483,23 @@ CFG_BUILD=`echo "${CFG_BUILD}" | sed 's/-pc-mingw32/-w64-mingw32/g'`
CFG_HOST=`echo "${CFG_HOST}" | sed 's/-pc-mingw32/-w64-mingw32/g'`
CFG_TARGET=`echo "${CFG_TARGET}" | sed 's/-pc-mingw32/-w64-mingw32/g'`
# Validate the release channel
case "$CFG_RELEASE_CHANNEL" in
(source | nightly | beta | stable)
;;
(*)
err "release channel must be 'source', 'nightly', 'beta' or 'stable'"
;;
esac
# Continue supporting the old --enable-nightly flag to transition the bots
# XXX Remove me
if [ $CFG_ENABLE_NIGHTLY -eq 1 ]
then
CFG_RELEASE_CHANNEL=nightly
putvar CFG_RELEASE_CHANNEL
fi
step_msg "looking for build programs"
probe_need CFG_PERL perl
@ -636,7 +655,7 @@ then
# check that gcc, cc and g++ all point to the same compiler.
# note that for xcode 5, g++ points to clang, not clang++
if !((chk_cc gcc clang && chk_cc g++ clang) ||
(chk_cc gcc gcc &&( chk_cc g++ g++ || chk g++ gcc))) then
(chk_cc gcc gcc &&( chk_cc g++ g++ || chk g++ gcc))); then
err "the gcc and g++ in your path point to different compilers.
Check which versions are in your path with gcc --version and g++ --version.
To resolve this problem, either fix your PATH or run configure with --enable-clang"

View File

@ -1,4 +1,4 @@
.TH RUSTC "1" "March 2014" "rustc 0.12.0-pre" "User Commands"
.TH RUSTC "1" "March 2014" "rustc 0.12.0" "User Commands"
.SH NAME
rustc \- The Rust compiler
.SH SYNOPSIS

View File

@ -1,4 +1,4 @@
.TH RUSTDOC "1" "March 2014" "rustdoc 0.12.0-pre" "User Commands"
.TH RUSTDOC "1" "March 2014" "rustdoc 0.12.0" "User Commands"
.SH NAME
rustdoc \- generate documentation from Rust source code
.SH SYNOPSIS

View File

@ -14,22 +14,32 @@
# The version number
CFG_RELEASE_NUM=0.12.0
CFG_RELEASE_LABEL=-pre
CFG_FILENAME_EXTRA=4e7c5e5c
ifndef CFG_ENABLE_NIGHTLY
# This is the normal version string
CFG_RELEASE=$(CFG_RELEASE_NUM)$(CFG_RELEASE_LABEL)
CFG_PACKAGE_VERS=$(CFG_RELEASE)
else
# Modify the version label for nightly builds
CFG_RELEASE=$(CFG_RELEASE_NUM)$(CFG_RELEASE_LABEL)-nightly
# When building nightly distributables just reuse the same "rust-nightly" name
# so when we upload we'll always override the previous nighly. This doesn't actually
# impact the version reported by rustc - it's just for file naming.
ifeq ($(CFG_RELEASE_CHANNEL),stable)
# This is the normal semver version string, e.g. "0.12.0", "0.12.0-nightly"
CFG_RELEASE=$(CFG_RELEASE_NUM)
# This is the string used in dist artifact file names, e.g. "0.12.0", "nightly"
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)
endif
ifeq ($(CFG_RELEASE_CHANNEL),beta)
CFG_RELEASE=$(CFG_RELEASE_NUM)-beta
# When building beta/nightly distributables just reuse the same "beta"
# name so when we upload we'll always override the previous
# nighly. This doesn't actually impact the version reported by rustc -
# it's just for file naming.
CFG_PACKAGE_VERS=beta
endif
ifeq ($(CFG_RELEASE_CHANNEL),nightly)
CFG_RELEASE=$(CFG_RELEASE_NUM)-nightly
CFG_PACKAGE_VERS=nightly
endif
ifeq ($(CFG_RELEASE_CHANNEL),source)
CFG_RELEASE=$(CFG_RELEASE_NUM)-pre
CFG_PACKAGE_VERS=$(CFG_RELEASE_NUM)-pre
endif
# The name of the package to use for creating tarballs, installers etc.
CFG_PACKAGE_NAME=rust-$(CFG_PACKAGE_VERS)

View File

@ -235,7 +235,7 @@ fn partial_sum(start: uint) -> f64 {
}
fn main() {
let mut futures = Vec::from_fn(1000, |ind| Future::spawn( proc() { partial_sum(ind) }));
let mut futures = Vec::from_fn(200, |ind| Future::spawn( proc() { partial_sum(ind) }));
let mut final_res = 0f64;
for ft in futures.iter_mut() {

View File

@ -29,8 +29,11 @@ $ curl -s https://static.rust-lang.org/rustup.sh | sudo sh
(If you're concerned about `curl | sudo sh`, please keep reading. Disclaimer
below.)
If you're on Windows, please [download this .exe and run
it](https://static.rust-lang.org/dist/rust-nightly-install.exe).
If you're on Windows, please download either the [32-bit
installer](https://static.rust-lang.org/dist/rust-nightly-i686-w64-mingw32.exe)
or the [64-bit
installer](https://static.rust-lang.org/dist/rust-nightly-x86_64-w64-mingw32.exe)
and run it.
If you decide you don't want Rust anymore, we'll be a bit sad, but that's okay.
Not every programming language is great for everyone. Just pass an argument to
@ -185,8 +188,8 @@ Next up is this line:
This line does all of the work in our little program. There are a number of
details that are important here. The first is that it's indented with four
spaces, not tabs. Please configure your editor of choice to insert four spaces
with the tab key. We provide some sample configurations for various editors
[here](https://github.com/rust-lang/rust/tree/master/src/etc).
with the tab key. We provide some [sample configurations for various
editors](https://github.com/rust-lang/rust/tree/master/src/etc).
The second point is the `println!()` part. This is calling a Rust **macro**,
which is how metaprogramming is done in Rust. If it were a function instead, it
@ -392,14 +395,10 @@ By the way, in these examples, `i` indicates that the number is an integer.
Rust is a statically typed language, which means that we specify our types up
front. So why does our first example compile? Well, Rust has this thing called
"[Hindley-Milner type
inference](http://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type_system)",
named after some really smart type theorists. If you clicked that link, don't
be scared: what this means for you is that Rust will attempt to infer the types
in your program, and it's pretty good at it. If it can infer the type, Rust
"type inference." If it can figure out what the type of something is, Rust
doesn't require you to actually type it out.
We can add the type if we want to. Types come after a colon (`:`):
We can add the type if we want to, though. Types come after a colon (`:`):
```{rust}
let x: int = 5;
@ -1281,15 +1280,15 @@ two main looping constructs: `for` and `while`.
The `for` loop is used to loop a particular number of times. Rust's `for` loops
work a bit differently than in other systems languages, however. Rust's `for`
loop doesn't look like this C `for` loop:
loop doesn't look like this "C style" `for` loop:
```{ignore,c}
```{c}
for (x = 0; x < 10; x++) {
printf( "%d\n", x );
}
```
It looks like this:
Instead, it looks like this:
```{rust}
for x in range(0i, 10i) {
@ -1312,10 +1311,9 @@ valid for the loop body. Once the body is over, the next value is fetched from
the iterator, and we loop another time. When there are no more values, the
`for` loop is over.
In our example, the `range` function is a function, provided by Rust, that
takes a start and an end position, and gives an iterator over those values. The
upper bound is exclusive, though, so our loop will print `0` through `9`, not
`10`.
In our example, `range` is a function that takes a start and an end position,
and gives an iterator over those values. The upper bound is exclusive, though,
so our loop will print `0` through `9`, not `10`.
Rust does not have the "C style" `for` loop on purpose. Manually controlling
each element of the loop is complicated and error prone, even for experienced C

View File

@ -86,10 +86,10 @@ There are questions that are asked quite often, and so we've made FAQs for them:
# The standard library
You can find function-level documentation for the entire standard library
[here](std/index.html). There's a list of crates on the left with more specific
sections, or you can use the search bar at the top to search for something if
you know its name.
We have [API documentation for the entire standard
library](std/index.html). There's a list of crates on the left with more
specific sections, or you can use the search bar at the top to search for
something if you know its name.
# External documentation

View File

@ -7,7 +7,7 @@
<!ENTITY rustIdent "[a-zA-Z_][a-zA-Z_0-9]*">
<!ENTITY rustIntSuf "([iu](8|16|32|64)?)?">
]>
<language name="Rust" version="0.12.0-pre" kateversion="2.4" section="Sources" extensions="*.rs" mimetype="text/x-rust" priority="15">
<language name="Rust" version="0.12.0" kateversion="2.4" section="Sources" extensions="*.rs" mimetype="text/x-rust" priority="15">
<highlighting>
<list name="fn">
<item> fn </item>

View File

@ -49,7 +49,6 @@ exceptions = [
"test/bench/shootout-mandelbrot.rs", # BSD
"test/bench/shootout-meteor.rs", # BSD
"test/bench/shootout-nbody.rs", # BSD
"test/bench/shootout-pidigits.rs", # BSD
"test/bench/shootout-regex-dna.rs", # BSD
"test/bench/shootout-reverse-complement.rs", # BSD
"test/bench/shootout-threadring.rs", # BSD

View File

@ -10,9 +10,6 @@
// FIXME: #13996: mark the `allocate` and `reallocate` return value as `noalias`
#[cfg(stage0, not(test))] use core::raw;
#[cfg(stage0, not(test))] use util;
/// Returns a pointer to `size` bytes of memory.
///
/// Behavior is undefined if the requested size is 0 or the alignment is not a
@ -111,21 +108,6 @@ unsafe fn exchange_free(ptr: *mut u8, size: uint, align: uint) {
deallocate(ptr, size, align);
}
#[cfg(stage0, not(test))]
#[lang="closure_exchange_malloc"]
#[inline]
#[allow(deprecated)]
unsafe fn closure_exchange_malloc(drop_glue: fn(*mut u8), size: uint,
align: uint) -> *mut u8 {
let total_size = util::get_box_size(size, align);
let p = allocate(total_size, 8);
let alloc = p as *mut raw::Box<()>;
(*alloc).drop_glue = drop_glue;
alloc as *mut u8
}
// The minimum alignment guaranteed by the architecture. This value is used to
// add fast paths for low alignment values. In practice, the alignment is a
// constant at the call site and the branch will be optimized out.
@ -155,9 +137,6 @@ mod imp {
flags: c_int) -> *mut c_void;
fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t,
flags: c_int) -> size_t;
#[cfg(stage0)]
fn je_dallocx(ptr: *mut c_void, flags: c_int);
#[cfg(not(stage0))]
fn je_sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
fn je_nallocx(size: size_t, flags: c_int) -> size_t;
fn je_malloc_stats_print(write_cb: Option<extern "C" fn(cbopaque: *mut c_void,
@ -209,14 +188,6 @@ mod imp {
}
#[inline]
#[cfg(stage0)]
pub unsafe fn deallocate(ptr: *mut u8, _size: uint, align: uint) {
let flags = align_to_flags(align);
je_dallocx(ptr as *mut c_void, flags)
}
#[inline]
#[cfg(not(stage0))]
pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) {
let flags = align_to_flags(align);
je_sdallocx(ptr as *mut c_void, size as size_t, flags)

View File

@ -14,13 +14,6 @@
//! These definitions are similar to their `ct` equivalents, but differ in that
//! these can be statically allocated and are slightly optimized for the runtime
#[cfg(stage0)]
#[doc(hidden)]
pub enum Piece<'a> {
String(&'a str),
Argument(Argument<'a>),
}
#[doc(hidden)]
pub struct Argument<'a> {
pub position: Position,

View File

@ -419,8 +419,76 @@ struct TwoWaySearcher {
memory: uint
}
// This is the Two-Way search algorithm, which was introduced in the paper:
// Crochemore, M., Perrin, D., 1991, Two-way string-matching, Journal of the ACM 38(3):651-675.
/*
This is the Two-Way search algorithm, which was introduced in the paper:
Crochemore, M., Perrin, D., 1991, Two-way string-matching, Journal of the ACM 38(3):651-675.
Here's some background information.
A *word* is a string of symbols. The *length* of a word should be a familiar
notion, and here we denote it for any word x by |x|.
(We also allow for the possibility of the *empty word*, a word of length zero).
If x is any non-empty word, then an integer p with 0 < p <= |x| is said to be a
*period* for x iff for all i with 0 <= i <= |x| - p - 1, we have x[i] == x[i+p].
For example, both 1 and 2 are periods for the string "aa". As another example,
the only period of the string "abcd" is 4.
We denote by period(x) the *smallest* period of x (provided that x is non-empty).
This is always well-defined since every non-empty word x has at least one period,
|x|. We sometimes call this *the period* of x.
If u, v and x are words such that x = uv, where uv is the concatenation of u and
v, then we say that (u, v) is a *factorization* of x.
Let (u, v) be a factorization for a word x. Then if w is a non-empty word such
that both of the following hold
- either w is a suffix of u or u is a suffix of w
- either w is a prefix of v or v is a prefix of w
then w is said to be a *repetition* for the factorization (u, v).
Just to unpack this, there are four possibilities here. Let w = "abc". Then we
might have:
- w is a suffix of u and w is a prefix of v. ex: ("lolabc", "abcde")
- w is a suffix of u and v is a prefix of w. ex: ("lolabc", "ab")
- u is a suffix of w and w is a prefix of v. ex: ("bc", "abchi")
- u is a suffix of w and v is a prefix of w. ex: ("bc", "a")
Note that the word vu is a repetition for any factorization (u,v) of x = uv,
so every factorization has at least one repetition.
If x is a string and (u, v) is a factorization for x, then a *local period* for
(u, v) is an integer r such that there is some word w such that |w| = r and w is
a repetition for (u, v).
We denote by local_period(u, v) the smallest local period of (u, v). We sometimes
call this *the local period* of (u, v). Provided that x = uv is non-empty, this
is well-defined (because each non-empty word has at least one factorization, as
noted above).
It can be proven that the following is an equivalent definition of a local period
for a factorization (u, v): any positive integer r such that x[i] == x[i+r] for
all i such that |u| - r <= i <= |u| - 1 and such that both x[i] and x[i+r] are
defined. (i.e. i > 0 and i + r < |x|).
Using the above reformulation, it is easy to prove that
1 <= local_period(u, v) <= period(uv)
A factorization (u, v) of x such that local_period(u,v) = period(x) is called a
*critical factorization*.
The algorithm hinges on the following theorem, which is stated without proof:
**Critical Factorization Theorem** Any word x has at least one critical
factorization (u, v) such that |u| < period(x).
The purpose of maximal_suffix is to find such a critical factorization.
*/
impl TwoWaySearcher {
fn new(needle: &[u8]) -> TwoWaySearcher {
let (crit_pos1, period1) = TwoWaySearcher::maximal_suffix(needle, false);
@ -436,15 +504,19 @@ impl TwoWaySearcher {
period = period2;
}
// This isn't in the original algorithm, as far as I'm aware.
let byteset = needle.iter()
.fold(0, |a, &b| (1 << ((b & 0x3f) as uint)) | a);
// The logic here (calculating crit_pos and period, the final if statement to see which
// period to use for the TwoWaySearcher) is essentially an implementation of the
// "small-period" function from the paper (p. 670)
// A particularly readable explanation of what's going on here can be found
// in Crochemore and Rytter's book "Text Algorithms", ch 13. Specifically
// see the code for "Algorithm CP" on p. 323.
//
// In the paper they check whether `needle.slice_to(crit_pos)` is a suffix of
// `needle.slice(crit_pos, crit_pos + period)`, which is precisely what this does
// What's going on is we have some critical factorization (u, v) of the
// needle, and we want to determine whether u is a suffix of
// v.slice_to(period). If it is, we use "Algorithm CP1". Otherwise we use
// "Algorithm CP2", which is optimized for when the period of the needle
// is large.
if needle.slice_to(crit_pos) == needle.slice(period, period + crit_pos) {
TwoWaySearcher {
crit_pos: crit_pos,
@ -466,6 +538,11 @@ impl TwoWaySearcher {
}
}
// One of the main ideas of Two-Way is that we factorize the needle into
// two halves, (u, v), and begin trying to find v in the haystack by scanning
// left to right. If v matches, we try to match u by scanning right to left.
// How far we can jump when we encounter a mismatch is all based on the fact
// that (u, v) is a critical factorization for the needle.
#[inline]
fn next(&mut self, haystack: &[u8], needle: &[u8], long_period: bool) -> Option<(uint, uint)> {
'search: loop {
@ -479,6 +556,9 @@ impl TwoWaySearcher {
((haystack[self.position + needle.len() - 1] & 0x3f)
as uint)) & 1 == 0 {
self.position += needle.len();
if !long_period {
self.memory = 0;
}
continue 'search;
}
@ -517,9 +597,9 @@ impl TwoWaySearcher {
}
}
// returns (i, p) where i is the "critical position", the starting index of
// of maximal suffix, and p is the period of the suffix
// see p. 668 of the paper
// Computes a critical factorization (u, v) of `arr`.
// Specifically, returns (i, p), where i is the starting index of v in some
// critical factorization (u, v) and p = period(v)
#[inline]
fn maximal_suffix(arr: &[u8], reversed: bool) -> (uint, uint) {
let mut left = -1; // Corresponds to i in the paper

View File

@ -26,6 +26,12 @@ fn strslice_issue_16589() {
check_contains_all_substrings("012345678901234567890123456789bcdabcdabcd");
}
#[test]
fn strslice_issue_16878() {
assert!(!"1234567ah012345678901ah".contains("hah"));
assert!(!"00abc01234567890123456789abc".contains("bcabc"));
}
#[test]
fn test_strslice_contains() {

View File

@ -19,6 +19,7 @@
//! ## Example
//!
//! ```rust
//! # #![allow(deprecated)]
//! use num::bigint::BigUint;
//! use std::num::{Zero, One};
//! use std::mem::replace;
@ -42,6 +43,7 @@
//! It's easy to generate large random numbers:
//!
//! ```rust
//! # #![allow(deprecated)]
//! use num::bigint::{ToBigInt, RandBigInt};
//! use std::rand;
//!

View File

@ -18,6 +18,7 @@
//! approximate a square root to arbitrary precision:
//!
//! ```
//! # #![allow(deprecated)]
//! extern crate num;
//!
//! use num::bigint::BigInt;
@ -46,7 +47,9 @@
#![feature(default_type_params)]
#![crate_name = "num"]
#![experimental]
#![deprecated = "This is now a cargo package located at: \
https://github.com/rust-lang/num"]
#![allow(deprecated)]
#![crate_type = "rlib"]
#![crate_type = "dylib"]
#![license = "MIT/ASL2"]

View File

@ -109,11 +109,6 @@ register_diagnostics!(
E0092,
E0093,
E0094,
E0095,
E0096,
E0097,
E0098,
E0099,
E0100,
E0101,
E0102,
@ -153,7 +148,6 @@ register_diagnostics!(
E0139,
E0140,
E0141,
E0142,
E0143,
E0144,
E0145,
@ -169,6 +163,5 @@ register_diagnostics!(
E0157,
E0158,
E0159,
E0160,
E0161
)

View File

@ -689,11 +689,7 @@ impl LintPass for UnusedResult {
ast::StmtSemi(ref expr, _) => &**expr,
_ => return
};
let t = ty::expr_ty(cx.tcx, expr);
match ty::get(t).sty {
ty::ty_nil | ty::ty_bot | ty::ty_bool => return,
_ => {}
}
match expr.node {
ast::ExprRet(..) => return,
_ => {}
@ -702,6 +698,7 @@ impl LintPass for UnusedResult {
let t = ty::expr_ty(cx.tcx, expr);
let mut warned = false;
match ty::get(t).sty {
ty::ty_nil | ty::ty_bot | ty::ty_bool => return,
ty::ty_struct(did, _) |
ty::ty_enum(did, _) => {
if ast_util::is_local(did) {
@ -1107,6 +1104,41 @@ impl LintPass for UnnecessaryParens {
}
}
declare_lint!(UNNECESSARY_IMPORT_BRACES, Allow,
"unnecessary braces around an imported item")
pub struct UnnecessaryImportBraces;
impl LintPass for UnnecessaryImportBraces {
fn get_lints(&self) -> LintArray {
lint_array!(UNNECESSARY_IMPORT_BRACES)
}
fn check_view_item(&mut self, cx: &Context, view_item: &ast::ViewItem) {
match view_item.node {
ast::ViewItemUse(ref view_path) => {
match view_path.node {
ast::ViewPathList(_, ref items, _) => {
if items.len() == 1 {
match items[0].node {
ast::PathListIdent {ref name, ..} => {
let m = format!("braces around {} is unnecessary",
token::get_ident(*name).get());
cx.span_lint(UNNECESSARY_IMPORT_BRACES, view_item.span,
m.as_slice());
},
_ => ()
}
}
}
_ => ()
}
},
_ => ()
}
}
}
declare_lint!(UNUSED_UNSAFE, Warn,
"unnecessary use of an `unsafe` block")

View File

@ -183,6 +183,7 @@ impl LintStore {
NonSnakeCase,
NonUppercaseStatics,
UnnecessaryParens,
UnnecessaryImportBraces,
UnusedUnsafe,
UnsafeBlock,
UnusedMut,

View File

@ -325,7 +325,7 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
};
DlDef(def::DefStaticMethod(did, provenance, fn_style))
}
Type | ForeignType => DlDef(def::DefTy(did)),
Type | ForeignType => DlDef(def::DefTy(did, false)),
Mod => DlDef(def::DefMod(did)),
ForeignMod => DlDef(def::DefForeignMod(did)),
StructVariant => {
@ -337,7 +337,7 @@ fn item_to_def_like(item: rbml::Doc, did: ast::DefId, cnum: ast::CrateNum)
DlDef(def::DefVariant(enum_did, did, false))
}
Trait => DlDef(def::DefTrait(did)),
Enum => DlDef(def::DefTy(did)),
Enum => DlDef(def::DefTy(did, true)),
Impl => DlImpl(did),
PublicField | InheritedField => DlField,
}

View File

@ -680,14 +680,14 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds {
let builtin_bounds = parse_builtin_bounds(st, |x,y| conv(x,y));
let mut param_bounds = ty::ParamBounds {
opt_region_bound: None,
region_bounds: Vec::new(),
builtin_bounds: builtin_bounds,
trait_bounds: Vec::new()
};
loop {
match next(st) {
'R' => {
param_bounds.opt_region_bound = Some(parse_region(st, |x, y| conv (x, y)));
param_bounds.region_bounds.push(parse_region(st, |x, y| conv (x, y)));
}
'I' => {
param_bounds.trait_bounds.push(Rc::new(parse_trait_ref(st, |x,y| conv(x,y))));

View File

@ -366,7 +366,7 @@ pub fn enc_existential_bounds(w: &mut SeekableMemWriter, cx: &ctxt, bs: &ty::Exi
pub fn enc_bounds(w: &mut SeekableMemWriter, cx: &ctxt, bs: &ty::ParamBounds) {
enc_builtin_bounds(w, cx, &bs.builtin_bounds);
for &r in bs.opt_region_bound.iter() {
for &r in bs.region_bounds.iter() {
mywrite!(w, "R");
enc_region(w, cx, r);
}

View File

@ -454,7 +454,7 @@ impl tr for def::Def {
def::DefVariant(e_did.tr(dcx), v_did.tr(dcx), is_s)
},
def::DefTrait(did) => def::DefTrait(did.tr(dcx)),
def::DefTy(did) => def::DefTy(did.tr(dcx)),
def::DefTy(did, is_enum) => def::DefTy(did.tr(dcx), is_enum),
def::DefPrimTy(p) => def::DefPrimTy(p),
def::DefTyParam(s, did, v) => def::DefTyParam(s, did.tr(dcx), v),
def::DefBinding(nid, bm) => def::DefBinding(dcx.tr_id(nid), bm),

View File

@ -25,7 +25,7 @@ pub enum Def {
DefArg(ast::NodeId, ast::BindingMode),
DefLocal(ast::NodeId, ast::BindingMode),
DefVariant(ast::DefId /* enum */, ast::DefId /* variant */, bool /* is_structure */),
DefTy(ast::DefId),
DefTy(ast::DefId, bool /* is_enum */),
DefTrait(ast::DefId),
DefPrimTy(ast::PrimTy),
DefTyParam(ParamSpace, ast::DefId, uint),
@ -62,7 +62,7 @@ impl Def {
match *self {
DefFn(id, _) | DefStaticMethod(id, _, _) | DefMod(id) |
DefForeignMod(id) | DefStatic(id, _) |
DefVariant(_, id, _) | DefTy(id) | DefTyParam(_, id, _) |
DefVariant(_, id, _) | DefTy(id, _) | DefTyParam(_, id, _) |
DefUse(id) | DefStruct(id) | DefTrait(id) | DefMethod(id, _) => {
id
}

View File

@ -131,8 +131,8 @@ enum LoopKind<'a> {
LoopLoop,
/// A `while` loop, with the given expression as condition.
WhileLoop(&'a Expr),
/// A `for` loop.
ForLoop,
/// A `for` loop, with the given pattern to bind.
ForLoop(&'a Pat),
}
#[deriving(PartialEq)]
@ -1024,8 +1024,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_loop(expr, WhileLoop(&**cond), &**blk, succ)
}
ExprForLoop(_, ref head, ref blk, _) => {
let ln = self.propagate_through_loop(expr, ForLoop, &**blk, succ);
ExprForLoop(ref pat, ref head, ref blk, _) => {
let ln = self.propagate_through_loop(expr, ForLoop(&**pat), &**blk, succ);
self.propagate_through_expr(&**head, ln)
}
@ -1355,7 +1355,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
expr.id, block_to_string(body));
let cond_ln = match kind {
LoopLoop | ForLoop => ln,
LoopLoop => ln,
ForLoop(ref pat) => self.define_bindings_in_pat(*pat, ln),
WhileLoop(ref cond) => self.propagate_through_expr(&**cond, ln),
};
let body_ln = self.with_loop_nodes(expr.id, succ, ln, |this| {
@ -1367,7 +1368,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
first_merge = false;
let new_cond_ln = match kind {
LoopLoop | ForLoop => ln,
LoopLoop => ln,
ForLoop(ref pat) => {
self.define_bindings_in_pat(*pat, ln)
}
WhileLoop(ref cond) => {
self.propagate_through_expr(&**cond, ln)
}
@ -1453,6 +1457,12 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
visit::walk_expr(this, expr);
}
ExprForLoop(ref pat, _, _, _) => {
this.pat_bindings(&**pat, |this, ln, var, sp, id| {
this.warn_about_unused(sp, id, ln, var);
});
}
// no correctness conditions related to liveness
ExprCall(..) | ExprMethodCall(..) | ExprIf(..) | ExprMatch(..) |
ExprWhile(..) | ExprLoop(..) | ExprIndex(..) | ExprField(..) |
@ -1461,7 +1471,7 @@ fn check_expr(this: &mut Liveness, expr: &Expr) {
ExprAgain(..) | ExprLit(_) | ExprBlock(..) |
ExprMac(..) | ExprAddrOf(..) | ExprStruct(..) | ExprRepeat(..) |
ExprParen(..) | ExprFnBlock(..) | ExprProc(..) | ExprUnboxedFn(..) |
ExprPath(..) | ExprBox(..) | ExprForLoop(..) => {
ExprPath(..) | ExprBox(..) => {
visit::walk_expr(this, expr);
}
}

View File

@ -531,7 +531,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
Ok(self.cat_rvalue_node(id, span, expr_ty))
}
def::DefMod(_) | def::DefForeignMod(_) | def::DefUse(_) |
def::DefTrait(_) | def::DefTy(_) | def::DefPrimTy(_) |
def::DefTrait(_) | def::DefTy(..) | def::DefPrimTy(_) |
def::DefTyParam(..) | def::DefTyParamBinder(..) | def::DefRegion(_) |
def::DefLabel(_) | def::DefSelfTy(..) | def::DefMethod(..) => {
Ok(Rc::new(cmt_ {

View File

@ -771,7 +771,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
def::DefFn(..) => ck("function"),
def::DefStatic(..) => ck("static"),
def::DefVariant(..) => ck("variant"),
def::DefTy(..) => ck("type"),
def::DefTy(_, false) => ck("type"),
def::DefTy(_, true) => ck("enum"),
def::DefTrait(..) => ck("trait"),
def::DefStruct(..) => ck("struct"),
def::DefMethod(_, Some(..)) => ck("trait method"),

View File

@ -1252,7 +1252,7 @@ impl<'a> Resolver<'a> {
sp);
name_bindings.define_type
(DefTy(local_def(item.id)), sp, is_public);
(DefTy(local_def(item.id), false), sp, is_public);
parent
}
@ -1264,7 +1264,7 @@ impl<'a> Resolver<'a> {
sp);
name_bindings.define_type
(DefTy(local_def(item.id)), sp, is_public);
(DefTy(local_def(item.id), true), sp, is_public);
for variant in (*enum_definition).variants.iter() {
self.build_reduced_graph_for_variant(
@ -1287,7 +1287,7 @@ impl<'a> Resolver<'a> {
let name_bindings = self.add_child(ident, parent.clone(), forbid, sp);
// Define a name in the type namespace.
name_bindings.define_type(DefTy(local_def(item.id)), sp, is_public);
name_bindings.define_type(DefTy(local_def(item.id), false), sp, is_public);
// If this is a newtype or unit-like struct, define a name
// in the value namespace as well
@ -1732,7 +1732,7 @@ impl<'a> Resolver<'a> {
match def {
DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
DefTy(def_id) => {
DefTy(def_id, _) => {
let type_def = child_name_bindings.type_def.borrow().clone();
match type_def {
Some(TypeNsDef { module_def: Some(module_def), .. }) => {
@ -1823,7 +1823,7 @@ impl<'a> Resolver<'a> {
is_public,
DUMMY_SP)
}
DefTy(_) => {
DefTy(..) => {
debug!("(building reduced graph for external \
crate) building type {}", final_ident);
@ -4320,7 +4320,7 @@ impl<'a> Resolver<'a> {
// If it's a typedef, give a note
match def {
DefTy(_) => {
DefTy(..) => {
self.session.span_note(
trait_reference.path.span,
format!("`type` aliases cannot \
@ -4381,7 +4381,7 @@ impl<'a> Resolver<'a> {
Some(ref t) => match t.node {
TyPath(ref path, None, path_id) => {
match this.resolve_path(id, path, TypeNS, true) {
Some((DefTy(def_id), lp)) if this.structs.contains_key(&def_id) => {
Some((DefTy(def_id, _), lp)) if this.structs.contains_key(&def_id) => {
let def = DefStruct(def_id);
debug!("(resolving struct) resolved `{}` to type {:?}",
token::get_ident(path.segments
@ -5440,7 +5440,7 @@ impl<'a> Resolver<'a> {
if allowed == Everything {
// Look for a field with the same name in the current self_type.
match self.def_map.borrow().find(&node_id) {
Some(&DefTy(did))
Some(&DefTy(did, _))
| Some(&DefStruct(did))
| Some(&DefVariant(_, did, _)) => match self.structs.find(&did) {
None => {}
@ -5582,7 +5582,7 @@ impl<'a> Resolver<'a> {
// structs, which wouldn't result in this error.)
match self.with_no_errors(|this|
this.resolve_path(expr.id, path, TypeNS, false)) {
Some((DefTy(struct_id), _))
Some((DefTy(struct_id, _), _))
if self.structs.contains_key(&struct_id) => {
self.resolve_error(expr.span,
format!("`{}` is a structure name, but \

View File

@ -226,7 +226,7 @@ impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
def::DefMod(_) |
def::DefForeignMod(_) => Some(recorder::ModRef),
def::DefStruct(_) => Some(recorder::StructRef),
def::DefTy(_) |
def::DefTy(..) |
def::DefTrait(_) => Some(recorder::TypeRef),
def::DefStatic(_, _) |
def::DefBinding(_, _) |

View File

@ -250,9 +250,7 @@ pub fn search_trait_and_supertraits_from_bound(tcx: &ty::ctxt,
* is the path to that trait/supertrait. Else `None`.
*/
for (bound_index, bound) in
transitive_bounds(tcx, &[caller_bound]).enumerate()
{
for bound in transitive_bounds(tcx, &[caller_bound]) {
if test(bound.def_id) {
let vtable_param = VtableParam { bound: bound };
return Some(vtable_param);

View File

@ -557,7 +557,7 @@ fn get_branches<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let tcx = bcx.tcx();
let mut found: Vec<Opt> = vec![];
for (i, br) in m.iter().enumerate() {
for br in m.iter() {
let cur = *br.pats.get(col);
let opt = match cur.node {
ast::PatLit(ref l) => ConstantValue(ConstantExpr(&**l)),

View File

@ -1380,7 +1380,11 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
assert_eq!(discr, 0);
match ty::expr_kind(bcx.tcx(), &*base.expr) {
ty::LvalueExpr => {
ty::RvalueDpsExpr | ty::RvalueDatumExpr if !ty::type_needs_drop(bcx.tcx(), ty) => {
bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
},
ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr"),
_ => {
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, &*base.expr, "base"));
for &(i, t) in base.fields.iter() {
let datum = base_datum.get_element(
@ -1389,11 +1393,7 @@ pub fn trans_adt<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
let dest = adt::trans_field_ptr(bcx, &*repr, addr, discr, i);
bcx = datum.store_to(bcx, dest);
}
},
ty::RvalueDpsExpr | ty::RvalueDatumExpr => {
bcx = trans_into(bcx, &*base.expr, SaveIn(addr));
},
ty::RvalueStmtExpr => bcx.tcx().sess.bug("unexpected expr kind for struct base expr")
}
}
}

View File

@ -1008,7 +1008,7 @@ pub enum type_err {
/// as well as the existential type parameter in an object type.
#[deriving(PartialEq, Eq, Hash, Clone, Show)]
pub struct ParamBounds {
pub opt_region_bound: Option<ty::Region>,
pub region_bounds: Vec<ty::Region>,
pub builtin_bounds: BuiltinBounds,
pub trait_bounds: Vec<Rc<TraitRef>>
}
@ -1016,7 +1016,8 @@ pub struct ParamBounds {
/// Bounds suitable for an existentially quantified type parameter
/// such as those that appear in object types or closure types. The
/// major difference between this case and `ParamBounds` is that
/// general purpose trait bounds are omitted.
/// general purpose trait bounds are omitted and there must be
/// *exactly one* region.
#[deriving(PartialEq, Eq, Hash, Clone, Show)]
pub struct ExistentialBounds {
pub region_bound: ty::Region,
@ -3789,7 +3790,8 @@ pub fn ty_sort_string(cx: &ctxt, t: t) -> String {
ty_enum(id, _) => format!("enum {}", item_path_str(cx, id)),
ty_box(_) => "Gc-ptr".to_string(),
ty_uniq(_) => "box".to_string(),
ty_vec(_, _) => "vector".to_string(),
ty_vec(_, Some(_)) => "array".to_string(),
ty_vec(_, None) => "unsized array".to_string(),
ty_ptr(_) => "*-ptr".to_string(),
ty_rptr(_, _) => "&-ptr".to_string(),
ty_bare_fn(_) => "extern fn".to_string(),
@ -4864,7 +4866,7 @@ pub fn required_region_bounds(tcx: &ctxt,
trait_bounds,
|trait_ref| {
let bounds = ty::bounds_for_trait_ref(tcx, &*trait_ref);
push_region_bounds(bounds.opt_region_bound.as_slice(),
push_region_bounds(bounds.region_bounds.as_slice(),
bounds.builtin_bounds,
&mut all_bounds);
debug!("from {}: bounds={} all_bounds={}",

View File

@ -287,7 +287,7 @@ impl TypeFoldable for ty::ExistentialBounds {
impl TypeFoldable for ty::ParamBounds {
fn fold_with<'tcx, F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::ParamBounds {
ty::ParamBounds {
opt_region_bound: self.opt_region_bound.fold_with(folder),
region_bounds: self.region_bounds.fold_with(folder),
builtin_bounds: self.builtin_bounds.fold_with(folder),
trait_bounds: self.trait_bounds.fold_with(folder),
}

View File

@ -438,7 +438,7 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
// FIXME(#12938): This is a hack until we have full support for
// DST.
match a_def {
def::DefTy(did) | def::DefStruct(did)
def::DefTy(did, _) | def::DefStruct(did)
if Some(did) == this.tcx().lang_items.owned_box() => {
if path.segments
.iter()
@ -462,7 +462,7 @@ pub fn ast_ty_to_builtin_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
"not enough type parameters supplied to `Box<T>`");
Some(ty::mk_err())
}
def::DefTy(did) | def::DefStruct(did)
def::DefTy(did, _) | def::DefStruct(did)
if Some(did) == this.tcx().lang_items.gc() => {
if path.segments
.iter()
@ -833,7 +833,7 @@ pub fn ast_ty_to_ty<'tcx, AC: AstConv<'tcx>, RS: RegionScope>(
result.substs.clone(),
bounds)
}
def::DefTy(did) | def::DefStruct(did) => {
def::DefTy(did, _) | def::DefStruct(did) => {
ast_path_to_ty(this, rscope, did, path).ty
}
def::DefTyParam(space, id, n) => {

View File

@ -2005,7 +2005,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let region_bounds =
ty::required_region_bounds(
self.tcx(),
param_bound.opt_region_bound.as_slice(),
param_bound.region_bounds.as_slice(),
param_bound.builtin_bounds,
param_bound.trait_bounds.as_slice());
for &r in region_bounds.iter() {
@ -4937,7 +4937,7 @@ pub fn polytype_for_def(fcx: &FnCtxt,
return polytype_for_def(fcx, sp, *inner);
}
def::DefTrait(_) |
def::DefTy(_) |
def::DefTy(..) |
def::DefPrimTy(_) |
def::DefTyParam(..)=> {
fcx.ccx.tcx.sess.span_bug(sp, "expected value, found type");

View File

@ -1880,7 +1880,7 @@ fn param_must_outlive(rcx: &Rcx,
let param_bound = param_env.bounds.get(param_ty.space, param_ty.idx);
param_bounds =
ty::required_region_bounds(rcx.tcx(),
param_bound.opt_region_bound.as_slice(),
param_bound.region_bounds.as_slice(),
param_bound.builtin_bounds,
param_bound.trait_bounds.as_slice());

View File

@ -327,7 +327,7 @@ impl<'a, 'tcx> Wf<'a, 'tcx> {
// Inspect bounds on this type parameter for any
// region bounds.
for &r in type_param_def.bounds.opt_region_bound.iter() {
for &r in type_param_def.bounds.region_bounds.iter() {
self.stack.push((r, Some(ty)));
self.accumulate_from_ty(type_param_ty);
self.stack.pop().unwrap();

View File

@ -1044,7 +1044,7 @@ fn ty_generics_for_trait(ccx: &CrateCtxt,
ident: special_idents::type_self,
def_id: local_def(param_id),
bounds: ty::ParamBounds {
opt_region_bound: None,
region_bounds: vec!(),
builtin_bounds: ty::empty_builtin_bounds(),
trait_bounds: vec!(self_trait_ref),
},
@ -1280,12 +1280,12 @@ fn conv_param_bounds(ccx: &CrateCtxt,
.map(|b| instantiate_trait_ref(ccx, b, param_ty.to_ty(ccx.tcx)))
.chain(unboxed_fn_ty_bounds)
.collect();
let opt_region_bound =
astconv::compute_opt_region_bound(
ccx.tcx, span, builtin_bounds, region_bounds.as_slice(),
trait_bounds.as_slice());
let region_bounds: Vec<ty::Region> =
region_bounds.move_iter()
.map(|r| ast_region_to_region(ccx.tcx, r))
.collect();
ty::ParamBounds {
opt_region_bound: opt_region_bound,
region_bounds: region_bounds,
builtin_bounds: builtin_bounds,
trait_bounds: trait_bounds,
}

View File

@ -1235,7 +1235,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> {
Some(&d) => d
};
match a_def {
def::DefTy(did) | def::DefStruct(did) => {
def::DefTy(did, _) | def::DefStruct(did) => {
let generics = ty::lookup_item_type(self.tcx, did).generics;
let expected =

View File

@ -87,7 +87,12 @@ fn try_inline_def(cx: &DocContext, tcx: &ty::ctxt,
ret.extend(build_impls(cx, tcx, did).into_iter());
clean::StructItem(build_struct(cx, tcx, did))
}
def::DefTy(did) => {
def::DefTy(did, false) => {
record_extern_fqn(cx, did, clean::TypeTypedef);
ret.extend(build_impls(cx, tcx, did).into_iter());
build_type(cx, tcx, did)
}
def::DefTy(did, true) => {
record_extern_fqn(cx, did, clean::TypeEnum);
ret.extend(build_impls(cx, tcx, did).into_iter());
build_type(cx, tcx, did)

View File

@ -1094,6 +1094,7 @@ pub enum TypeKind {
TypeStruct,
TypeTrait,
TypeVariant,
TypeTypedef,
}
impl Primitive {
@ -2049,7 +2050,8 @@ fn resolve_type(cx: &DocContext, path: Path,
fn register_def(cx: &DocContext, def: def::Def) -> ast::DefId {
let (did, kind) = match def {
def::DefFn(i, _) => (i, TypeFunction),
def::DefTy(i) => (i, TypeEnum),
def::DefTy(i, false) => (i, TypeTypedef),
def::DefTy(i, true) => (i, TypeEnum),
def::DefTrait(i) => (i, TypeTrait),
def::DefStruct(i) => (i, TypeStruct),
def::DefMod(i) => (i, TypeModule),

View File

@ -45,7 +45,7 @@ impl ItemType {
match *self {
Module => "mod",
Struct => "struct",
Enum => "type",
Enum => "enum",
Function => "fn",
Typedef => "type",
Static => "static",

View File

@ -308,6 +308,7 @@ pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) ->
clean::TypeModule => item_type::Module,
clean::TypeStatic => item_type::Static,
clean::TypeVariant => item_type::Variant,
clean::TypeTypedef => item_type::Typedef,
}))
}).collect()
}).unwrap_or(HashMap::new());

View File

@ -229,6 +229,8 @@ nav.sub {
.content .highlighted.enum { background-color: #b4d1b9; }
.content .highlighted.struct { background-color: #e7b1a0; }
.content .highlighted.fn { background-color: #c6afb3; }
.content .highlighted.method { background-color: #c6afb3; }
.content .highlighted.ffi { background-color: #c6afb3; }
.docblock.short.nowrap {
display: block;
@ -336,11 +338,13 @@ a {
p a { color: #4e8bca; }
p a:hover { text-decoration: underline; }
.content span.trait, .block a.current.trait { color: #ed9603; }
.content span.mod, .block a.current.mod { color: #4d76ae; }
.content span.enum, .block a.current.enum { color: #5e9766; }
.content span.struct, .block a.current.struct { color: #e53700; }
.content span.fn, .block a.current.fn { color: #8c6067; }
.content span.trait, .content a.trait, .block a.current.trait { color: #ed9603; }
.content span.mod, .content a.mod, block a.current.mod { color: #4d76ae; }
.content span.enum, .content a.enum, .block a.current.enum { color: #5e9766; }
.content span.struct, .content a.struct, .block a.current.struct { color: #e53700; }
.content span.fn, .content a.fn, .block a.current.fn { color: #8c6067; }
.content span.method, .content a.method, .block a.current.method { color: #8c6067; }
.content span.ffi, .content a.ffi, .block a.current.ffi { color: #8c6067; }
.content .fnname { color: #8c6067; }
.search-input {

View File

@ -555,7 +555,7 @@
// `rustdoc::html::item_type::ItemType` type in Rust.
var itemTypes = ["mod",
"struct",
"type",
"enum",
"fn",
"type",
"static",

View File

@ -234,6 +234,7 @@ pub enum ErrorCode {
KeyMustBeAString,
ExpectedColon,
TrailingCharacters,
TrailingComma,
InvalidEscape,
InvalidUnicodeCodePoint,
LoneLeadingSurrogateInHexEscape,
@ -274,6 +275,7 @@ pub fn error_str(error: ErrorCode) -> &'static str {
KeyMustBeAString => "key must be a string",
ExpectedColon => "expected `:`",
TrailingCharacters => "trailing characters",
TrailingComma => "trailing comma",
InvalidEscape => "invalid escape",
UnrecognizedHex => "invalid \\u escape (unrecognized hex)",
NotFourDigit => "invalid \\u escape (not four digits)",
@ -1681,7 +1683,11 @@ impl<T: Iterator<char>> Parser<T> {
fn parse_object(&mut self, first: bool) -> JsonEvent {
if self.ch_is('}') {
if !first {
self.stack.pop();
if self.stack.is_empty() {
return self.error_event(TrailingComma);
} else {
self.stack.pop();
}
}
if self.stack.is_empty() {
self.state = ParseBeforeFinish;
@ -2377,7 +2383,7 @@ mod tests {
F64Value, StringValue, NullValue, SyntaxError, Key, Index, Stack,
InvalidSyntax, InvalidNumber, EOFWhileParsingObject, EOFWhileParsingList,
EOFWhileParsingValue, EOFWhileParsingString, KeyMustBeAString, ExpectedColon,
TrailingCharacters};
TrailingCharacters, TrailingComma};
use std::{i64, u64, f32, f64, io};
use std::collections::TreeMap;
@ -3379,6 +3385,7 @@ mod tests {
}
}
}
#[test]
#[ignore(cfg(target_word_size = "32"))] // FIXME(#14064)
fn test_read_object_streaming() {
@ -3393,6 +3400,7 @@ mod tests {
assert_eq!(last_event("{\"a\":1"), Error(SyntaxError(EOFWhileParsingObject, 1, 7)));
assert_eq!(last_event("{\"a\":1 1"), Error(SyntaxError(InvalidSyntax, 1, 8)));
assert_eq!(last_event("{\"a\":1,"), Error(SyntaxError(EOFWhileParsingObject, 1, 8)));
assert_eq!(last_event("{\"a\":1,}"), Error(SyntaxError(TrailingComma, 1, 8)));
assert_stream_equal(
"{}",

View File

@ -19,8 +19,7 @@ pub mod addrinfo;
pub mod tcp;
pub mod udp;
pub mod ip;
// FIXME(#12093) - this should not be called unix
pub mod unix;
pub mod pipe;
fn to_rtio(ip: IpAddr) -> rtio::IpAddr {
match ip {

View File

@ -46,7 +46,7 @@ impl UnixStream {
///
/// ```rust
/// # #![allow(unused_must_use)]
/// use std::io::net::unix::UnixStream;
/// use std::io::net::pipe::UnixStream;
///
/// let server = Path::new("path/to/my/socket");
/// let mut stream = UnixStream::connect(&server);
@ -164,7 +164,7 @@ impl UnixListener {
/// # fn main() {}
/// # fn foo() {
/// # #![allow(unused_must_use)]
/// use std::io::net::unix::UnixListener;
/// use std::io::net::pipe::UnixListener;
/// use std::io::{Listener, Acceptor};
///
/// let server = Path::new("/path/to/my/socket");

View File

@ -34,7 +34,7 @@ macro_rules! iotest (
use io::net::ip::*;
use io::net::udp::*;
#[cfg(unix)]
use io::net::unix::*;
use io::net::pipe::*;
use io::timer::*;
use io::process::*;
use rt::running_on_valgrind;

View File

@ -434,8 +434,8 @@ pub mod builtin {
/// # Example
///
/// ```rust
/// let home: &'static str = env!("HOME");
/// println!("the home directory at the time of compiling was: {}", home);
/// let path: &'static str = env!("PATH");
/// println!("the $PATH variable at the time of compiling was: {}", path);
/// ```
#[macro_export]
macro_rules! env( ($name:expr) => ({ /* compiler built-in */ }) )

View File

@ -88,14 +88,13 @@ use std::mem;
use std::rc::Rc;
use std::iter;
#[allow(non_camel_case_types)]
#[deriving(PartialEq)]
pub enum restriction {
UNRESTRICTED,
RESTRICT_STMT_EXPR,
RESTRICT_NO_BAR_OP,
RESTRICT_NO_BAR_OR_DOUBLEBAR_OP,
RESTRICT_NO_STRUCT_LITERAL,
bitflags! {
flags Restrictions: u8 {
static Unrestricted = 0b0000,
static RestrictionStmtExpr = 0b0001,
static RestrictionNoBarOp = 0b0010,
static RestrictionNoStructLiteral = 0b0100
}
}
type ItemInfo = (Ident, Item_, Option<Vec<Attribute> >);
@ -314,7 +313,7 @@ pub struct Parser<'a> {
pub buffer_start: int,
pub buffer_end: int,
pub tokens_consumed: uint,
pub restriction: restriction,
pub restrictions: Restrictions,
pub quote_depth: uint, // not (yet) related to the quasiquoter
pub reader: Box<Reader+'a>,
pub interner: Rc<token::IdentInterner>,
@ -383,7 +382,7 @@ impl<'a> Parser<'a> {
buffer_start: 0,
buffer_end: 0,
tokens_consumed: 0,
restriction: UNRESTRICTED,
restrictions: Unrestricted,
quote_depth: 0,
obsolete_set: HashSet::new(),
mod_path_stack: Vec::new(),
@ -2189,7 +2188,7 @@ impl<'a> Parser<'a> {
if self.token == token::LBRACE {
// This is a struct literal, unless we're prohibited
// from parsing struct literals here.
if self.restriction != RESTRICT_NO_STRUCT_LITERAL {
if !self.restrictions.contains(RestrictionNoStructLiteral) {
// It's a struct literal.
self.bump();
let mut fields = Vec::new();
@ -2651,12 +2650,9 @@ impl<'a> Parser<'a> {
// Prevent dynamic borrow errors later on by limiting the
// scope of the borrows.
match (&self.token, &self.restriction) {
(&token::BINOP(token::OR), &RESTRICT_NO_BAR_OP) => return lhs,
(&token::BINOP(token::OR),
&RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
(&token::OROR, &RESTRICT_NO_BAR_OR_DOUBLEBAR_OP) => return lhs,
_ => { }
if self.token == token::BINOP(token::OR) &&
self.restrictions.contains(RestrictionNoBarOp) {
return lhs;
}
let cur_opt = token_to_binop(&self.token);
@ -2696,15 +2692,16 @@ impl<'a> Parser<'a> {
pub fn parse_assign_expr(&mut self) -> P<Expr> {
let lo = self.span.lo;
let lhs = self.parse_binops();
let restrictions = self.restrictions & RestrictionNoStructLiteral;
match self.token {
token::EQ => {
self.bump();
let rhs = self.parse_expr();
let rhs = self.parse_expr_res(restrictions);
self.mk_expr(lo, rhs.span.hi, ExprAssign(lhs, rhs))
}
token::BINOPEQ(op) => {
self.bump();
let rhs = self.parse_expr();
let rhs = self.parse_expr_res(restrictions);
let aop = match op {
token::PLUS => BiAdd,
token::MINUS => BiSub,
@ -2730,7 +2727,7 @@ impl<'a> Parser<'a> {
/// Parse an 'if' expression ('if' token already eaten)
pub fn parse_if_expr(&mut self) -> P<Expr> {
let lo = self.last_span.lo;
let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
let cond = self.parse_expr_res(RestrictionNoStructLiteral);
let thn = self.parse_block();
let mut els: Option<P<Expr>> = None;
let mut hi = thn.span.hi;
@ -2791,7 +2788,7 @@ impl<'a> Parser<'a> {
let lo = self.last_span.lo;
let pat = self.parse_pat();
self.expect_keyword(keywords::In);
let expr = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
let expr = self.parse_expr_res(RestrictionNoStructLiteral);
let loop_block = self.parse_block();
let hi = self.span.hi;
@ -2800,7 +2797,7 @@ impl<'a> Parser<'a> {
pub fn parse_while_expr(&mut self, opt_ident: Option<ast::Ident>) -> P<Expr> {
let lo = self.last_span.lo;
let cond = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
let cond = self.parse_expr_res(RestrictionNoStructLiteral);
let body = self.parse_block();
let hi = body.span.hi;
return self.mk_expr(lo, hi, ExprWhile(cond, body, opt_ident));
@ -2815,7 +2812,7 @@ impl<'a> Parser<'a> {
fn parse_match_expr(&mut self) -> P<Expr> {
let lo = self.last_span.lo;
let discriminant = self.parse_expr_res(RESTRICT_NO_STRUCT_LITERAL);
let discriminant = self.parse_expr_res(RestrictionNoStructLiteral);
self.commit_expr_expecting(&*discriminant, token::LBRACE);
let mut arms: Vec<Arm> = Vec::new();
while self.token != token::RBRACE {
@ -2834,7 +2831,7 @@ impl<'a> Parser<'a> {
guard = Some(self.parse_expr());
}
self.expect(&token::FAT_ARROW);
let expr = self.parse_expr_res(RESTRICT_STMT_EXPR);
let expr = self.parse_expr_res(RestrictionStmtExpr);
let require_comma =
!classify::expr_is_simple_block(&*expr)
@ -2856,15 +2853,15 @@ impl<'a> Parser<'a> {
/// Parse an expression
pub fn parse_expr(&mut self) -> P<Expr> {
return self.parse_expr_res(UNRESTRICTED);
return self.parse_expr_res(Unrestricted);
}
/// Parse an expression, subject to the given restriction
pub fn parse_expr_res(&mut self, r: restriction) -> P<Expr> {
let old = self.restriction;
self.restriction = r;
/// Parse an expression, subject to the given restrictions
pub fn parse_expr_res(&mut self, r: Restrictions) -> P<Expr> {
let old = self.restrictions;
self.restrictions = r;
let e = self.parse_assign_expr();
self.restriction = old;
self.restrictions = old;
return e;
}
@ -3153,9 +3150,9 @@ impl<'a> Parser<'a> {
self.look_ahead(2, |t| {
*t != token::COMMA && *t != token::RBRACKET
}) {
let start = self.parse_expr_res(RESTRICT_NO_BAR_OP);
let start = self.parse_expr_res(RestrictionNoBarOp);
self.eat(&token::DOTDOT);
let end = self.parse_expr_res(RESTRICT_NO_BAR_OP);
let end = self.parse_expr_res(RestrictionNoBarOp);
pat = PatRange(start, end);
} else if is_plain_ident(&self.token) && !can_be_enum_or_struct {
let id = self.parse_ident();
@ -3441,7 +3438,7 @@ impl<'a> Parser<'a> {
check_expected_item(self, found_attrs);
// Remainder are line-expr stmts.
let e = self.parse_expr_res(RESTRICT_STMT_EXPR);
let e = self.parse_expr_res(RestrictionStmtExpr);
P(spanned(lo, e.span.hi, StmtExpr(e, ast::DUMMY_NODE_ID)))
}
}
@ -3450,7 +3447,7 @@ impl<'a> Parser<'a> {
/// Is this expression a successfully-parsed statement?
fn expr_is_complete(&mut self, e: &Expr) -> bool {
self.restriction == RESTRICT_STMT_EXPR &&
self.restrictions.contains(RestrictionStmtExpr) &&
!classify::expr_requires_semi_to_be_stmt(e)
}

View File

@ -1,3 +1,12 @@
S 2014-09-16 828e075
winnt-x86_64 ce1e9d7f6967bfa368853e7c968e1626cc319951
winnt-i386 a8bd994666dfe683a5d7922c7998500255780724
linux-x86_64 88ff474db96c6ffc5c1dc7a43442cbe1cd88c8a2
linux-i386 7a731891f726c8a0590b142a4e8924c5e8b22e8d
freebsd-x86_64 e67a56f76484f775cd4836dedb2d1069ab5d7921
macos-i386 f48023648a77e89086f4a2b39d76b09e4fff032d
macos-x86_64 2ad6457b2b3036f87eae7581d64ee5341a07fb06
S 2014-09-10 6faa4f3
winnt-x86_64 939eb546469cb936441cff3b6f2478f562f77c46
winnt-i386 cfe4f8b519bb9d62588f9310a8f94bc919d5423b

View File

@ -24,6 +24,7 @@ mod foo {
pub fn b() {}
pub struct c;
pub enum d {}
pub type e = int;
pub struct A(());
@ -36,6 +37,7 @@ mod foo {
pub fn reexported_b() {}
pub struct reexported_c;
pub enum reexported_d {}
pub type reexported_e = int;
}
pub mod bar {
@ -43,14 +45,17 @@ pub mod bar {
pub use foo::reexported_b as f;
pub use foo::reexported_c as g;
pub use foo::reexported_d as h;
pub use foo::reexported_e as i;
}
pub static a: int = 0;
pub fn b() {}
pub struct c;
pub enum d {}
pub type e = int;
static i: int = 0;
fn j() {}
struct k;
enum l {}
static j: int = 0;
fn k() {}
struct l;
enum m {}
type n = int;

View File

@ -1,128 +0,0 @@
// The Computer Language Benchmarks Game
// http://benchmarksgame.alioth.debian.org/
//
// contributed by the Rust Project Developers
// Copyright (c) 2013-2014 The Rust Project Developers
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// - Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// - Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in
// the documentation and/or other materials provided with the
// distribution.
//
// - Neither the name of "The Computer Language Benchmarks Game" nor
// the name of "The Computer Language Shootout Benchmarks" nor the
// names of its contributors may be used to endorse or promote
// products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
// OF THE POSSIBILITY OF SUCH DAMAGE.
extern crate num;
use std::from_str::FromStr;
use std::num::One;
use std::num::Zero;
use std::num::FromPrimitive;
use num::Integer;
use num::bigint::BigInt;
struct Context {
numer: BigInt,
accum: BigInt,
denom: BigInt,
}
impl Context {
fn new() -> Context {
Context {
numer: One::one(),
accum: Zero::zero(),
denom: One::one(),
}
}
fn from_int(i: int) -> BigInt {
FromPrimitive::from_int(i).unwrap()
}
fn extract_digit(&self) -> int {
if self.numer > self.accum {return -1;}
let (q, r) =
(self.numer * Context::from_int(3) + self.accum)
.div_rem(&self.denom);
if r + self.numer >= self.denom {return -1;}
q.to_int().unwrap()
}
fn next_term(&mut self, k: int) {
let y2 = Context::from_int(k * 2 + 1);
self.accum = (self.accum + (self.numer << 1)) * y2;
self.numer = self.numer * Context::from_int(k);
self.denom = self.denom * y2;
}
fn eliminate_digit(&mut self, d: int) {
let d = Context::from_int(d);
let ten = Context::from_int(10);
self.accum = (self.accum - self.denom * d) * ten;
self.numer = self.numer * ten;
}
}
fn pidigits(n: int) {
let mut k = 0;
let mut context = Context::new();
for i in range(1, n + 1) {
let mut d;
loop {
k += 1;
context.next_term(k);
d = context.extract_digit();
if d != -1 {break;}
}
print!("{}", d);
if i % 10 == 0 {print!("\t:{}\n", i);}
context.eliminate_digit(d);
}
let m = n % 10;
if m != 0 {
for _ in range(m, 10) { print!(" "); }
print!("\t:{}\n", n);
}
}
fn main() {
let args = std::os::args();
let args = args.as_slice();
let n = if args.len() < 2 {
512
} else {
FromStr::from_str(args[1].as_slice()).unwrap()
};
pidigits(n);
}

View File

@ -0,0 +1,16 @@
// 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.
fn main() {
let _x: int = [1i, 2, 3]; //~ ERROR expected int, found array
let x: &[int] = &[1, 2, 3];
let _y: &int = x; //~ ERROR expected int, found unsized array
}

View File

@ -0,0 +1,37 @@
// 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 the parser does not attempt to parse struct literals
// within assignments in if expressions.
struct Foo {
foo: uint
}
fn main() {
let x = 1u;
let y: Foo;
// `x { ... }` should not be interpreted as a struct literal here
if x = x {
//~^ ERROR mismatched types: expected `bool`, found `()` (expected bool, found ())
println!("{}", x);
}
// Explicit parentheses on the left should match behavior of above
if (x = x) {
//~^ ERROR mismatched types: expected `bool`, found `()` (expected bool, found ())
println!("{}", x);
}
// The struct literal interpretation is fine with explicit parentheses on the right
if y = (Foo { foo: x }) {
//~^ ERROR mismatched types: expected `bool`, found `()` (expected bool, found ())
println!("{}", x);
}
}

View File

@ -0,0 +1,21 @@
// 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.
#![deny(unnecessary_import_braces)]
#![allow(dead_code)]
#![allow(unused_imports)]
use test::{A}; //~ ERROR braces around A is unnecessary
mod test {
pub struct A;
}
fn main() {}

View File

@ -82,5 +82,23 @@ fn f4b() -> int {
}
}
fn f5a() {
for x in range(1i, 10) { }
//~^ ERROR unused variable: `x`
}
fn f5b() {
for (x, _) in [1i, 2, 3].iter().enumerate() { }
//~^ ERROR unused variable: `x`
}
fn f5c() {
for (_, x) in [1i, 2, 3].iter().enumerate() {
//~^ ERROR unused variable: `x`
continue;
std::os::set_exit_status(*x); //~ WARNING unreachable statement
}
}
fn main() {
}

View File

@ -35,10 +35,10 @@ fn test<
'a,
'b,
A:IsStatic,
B:Is<'a>+Is2<'b>, //~ ERROR ambiguous lifetime bound
B:Is<'a>+Is2<'b>, // OK in a parameter, but not an object type.
C:'b+Is<'a>+Is2<'b>,
D:Is<'a>+Is2<'static>,
E:'a+'b //~ ERROR only a single explicit lifetime bound is permitted
E:'a+'b // OK in a parameter, but not an object type.
>() { }
fn main() { }

View File

@ -0,0 +1,32 @@
// 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.
// Various tests where we over type parameters with multiple lifetime
// bounds.
trait SomeTrait { fn get(&self) -> int; }
fn make_object_good1<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'a> {
// A outlives 'a AND 'b...
box v as Box<SomeTrait+'a> // ...hence this type is safe.
}
fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'b> {
// A outlives 'a AND 'b...
box v as Box<SomeTrait+'b> // ...hence this type is safe.
}
fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<SomeTrait+'c> {
// A outlives 'a AND 'b...but not 'c.
box v as Box<SomeTrait+'a> //~ ERROR mismatched types
}
fn main() {
}

View File

@ -20,22 +20,26 @@ fn main() {
static_priv_by_default::b;
static_priv_by_default::c;
foo::<static_priv_by_default::d>();
foo::<static_priv_by_default::e>();
// publicly re-exported items should be available
static_priv_by_default::bar::e;
static_priv_by_default::bar::f;
static_priv_by_default::bar::g;
foo::<static_priv_by_default::bar::h>();
foo::<static_priv_by_default::bar::i>();
// private items at the top should be inaccessible
static_priv_by_default::i;
//~^ ERROR: static `i` is private
static_priv_by_default::j;
//~^ ERROR: function `j` is private
//~^ ERROR: static `j` is private
static_priv_by_default::k;
//~^ ERROR: struct `k` is private
foo::<static_priv_by_default::l>();
//~^ ERROR: type `l` is private
//~^ ERROR: function `k` is private
static_priv_by_default::l;
//~^ ERROR: struct `l` is private
foo::<static_priv_by_default::m>();
//~^ ERROR: enum `m` is private
foo::<static_priv_by_default::n>();
//~^ ERROR: type `n` is private
// public items in a private mod should be inaccessible
static_priv_by_default::foo::a;
@ -45,5 +49,7 @@ fn main() {
static_priv_by_default::foo::c;
//~^ ERROR: struct `c` is private
foo::<static_priv_by_default::foo::d>();
//~^ ERROR: type `d` is private
//~^ ERROR: enum `d` is private
foo::<static_priv_by_default::foo::e>();
//~^ ERROR: type `e` is private
}

View File

@ -0,0 +1,34 @@
// 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.
static mut DROPPED: [bool, ..2] = [false, false];
struct A(uint);
struct Foo { _a: A, _b: int }
impl Drop for A {
fn drop(&mut self) {
let A(i) = *self;
unsafe { DROPPED[i] = true; }
}
}
fn main() {
{
Foo {
_a: A(0),
..Foo { _a: A(1), _b: 2 }
};
}
unsafe {
assert!(DROPPED[0]);
assert!(DROPPED[1]);
}
}

View File

@ -0,0 +1,30 @@
// 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.
// A test where we (successfully) close over a reference into
// an object.
trait SomeTrait { fn get(&self) -> int; }
impl<'a> SomeTrait for &'a int {
fn get(&self) -> int {
**self
}
}
fn make_object<'a,A:SomeTrait+'a>(v: A) -> Box<SomeTrait+'a> {
box v as Box<SomeTrait+'a>
}
fn main() {
let i: int = 22;
let obj = make_object(&i);
assert_eq!(22, obj.get());
}