Auto merge of #28807 - Manishearth:rollup, r=Manishearth
- Successful merges: #28554, #28686, #28786, #28788, #28791, #28797 - Failed merges:
This commit is contained in:
commit
70076ec8b2
7 changed files with 155 additions and 9 deletions
|
|
@ -61,8 +61,9 @@ Language](http://www.cs.indiana.edu/~eholk/papers/hips2013.pdf). Early GPU work
|
|||
Rust](http://scialex.github.io/reenix.pdf). Undergrad paper by Alex
|
||||
Light.
|
||||
* [Evaluation of performance and productivity metrics of potential
|
||||
programming languages in the HPC environment](). Bachelor's thesis by
|
||||
Florian Wilkens. Compares C, Go and Rust.
|
||||
programming languages in the HPC environment]
|
||||
(http://octarineparrot.com/assets/mrfloya-thesis-ba.pdf).
|
||||
Bachelor's thesis by Florian Wilkens. Compares C, Go and Rust.
|
||||
* [Nom, a byte oriented, streaming, zero copy, parser combinators library
|
||||
in Rust](http://spw15.langsec.org/papers/couprie-nom.pdf). By
|
||||
Geoffroy Couprie, research for VLC.
|
||||
|
|
@ -77,4 +78,4 @@ Language](http://www.cs.indiana.edu/~eholk/papers/hips2013.pdf). Early GPU work
|
|||
Farnstrand's master's thesis.
|
||||
* [Session Types for
|
||||
Rust](http://munksgaard.me/papers/laumann-munksgaard-larsen.pdf). Philip
|
||||
Munksgaard's master's thesis. Research for Servo.
|
||||
Munksgaard's master's thesis. Research for Servo.
|
||||
|
|
|
|||
|
|
@ -148,6 +148,81 @@ use super::range::RangeArgument;
|
|||
/// if the vector's length is increased to 11, it will have to reallocate, which
|
||||
/// can be slow. For this reason, it is recommended to use `Vec::with_capacity`
|
||||
/// whenever possible to specify how big the vector is expected to get.
|
||||
///
|
||||
/// # Guarantees
|
||||
///
|
||||
/// Due to its incredibly fundamental nature, Vec makes a lot of guarantees
|
||||
/// about its design. This ensures that it's as low-overhead as possible in
|
||||
/// the general case, and can be correctly manipulated in primitive ways
|
||||
/// by unsafe code. Note that these guarantees refer to an unqualified `Vec<T>`.
|
||||
/// If additional type parameters are added (e.g. to support custom allocators),
|
||||
/// overriding their defaults may change the behavior.
|
||||
///
|
||||
/// Most fundamentally, Vec is and always will be a (pointer, capacity, length)
|
||||
/// triplet. No more, no less. The order of these fields is completely
|
||||
/// unspecified, and you should use the appropriate methods to modify these.
|
||||
/// The pointer will never be null, so this type is null-pointer-optimized.
|
||||
///
|
||||
/// However, the pointer may not actually point to allocated memory. In particular,
|
||||
/// if you construct a Vec with capacity 0 via `Vec::new()`, `vec![]`,
|
||||
/// `Vec::with_capacity(0)`, or by calling `shrink_to_fit()` on an empty Vec, it
|
||||
/// will not allocate memory. Similarly, if you store zero-sized types inside
|
||||
/// a Vec, it will not allocate space for them. *Note that in this case the
|
||||
/// Vec may not report a `capacity()` of 0*. Vec will allocate if and only
|
||||
/// if `mem::size_of::<T>() * capacity() > 0`. In general, Vec's allocation
|
||||
/// details are subtle enough that it is strongly recommended that you only
|
||||
/// free memory allocated by a Vec by creating a new Vec and dropping it.
|
||||
///
|
||||
/// If a Vec *has* allocated memory, then the memory it points to is on the heap
|
||||
/// (as defined by the allocator Rust is configured to use by default), and its
|
||||
/// pointer points to `len()` initialized elements in order (what you would see
|
||||
/// if you coerced it to a slice), followed by `capacity() - len()` logically
|
||||
/// uninitialized elements.
|
||||
///
|
||||
/// Vec will never perform a "small optimization" where elements are actually
|
||||
/// stored on the stack for two reasons:
|
||||
///
|
||||
/// * It would make it more difficult for unsafe code to correctly manipulate
|
||||
/// a Vec. The contents of a Vec wouldn't have a stable address if it were
|
||||
/// only moved, and it would be more difficult to determine if a Vec had
|
||||
/// actually allocated memory.
|
||||
///
|
||||
/// * It would penalize the general case, incurring an additional branch
|
||||
/// on every access.
|
||||
///
|
||||
/// Vec will never automatically shrink itself, even if completely empty. This
|
||||
/// ensures no unnecessary allocations or deallocations occur. Emptying a Vec
|
||||
/// and then filling it back up to the same `len()` should incur no calls to
|
||||
/// the allocator. If you wish to free up unused memory, use `shrink_to_fit`.
|
||||
///
|
||||
/// `push` and `insert` will never (re)allocate if the reported capacity is
|
||||
/// sufficient. `push` and `insert` *will* (re)allocate if `len() == capacity()`.
|
||||
/// That is, the reported capacity is completely accurate, and can be relied on.
|
||||
/// It can even be used to manually free the memory allocated by a Vec if
|
||||
/// desired. Bulk insertion methods *may* reallocate, even when not necessary.
|
||||
///
|
||||
/// Vec does not guarantee any particular growth strategy when reallocating
|
||||
/// when full, nor when `reserve` is called. The current strategy is basic
|
||||
/// and it may prove desirable to use a non-constant growth factor. Whatever
|
||||
/// strategy is used will of course guarantee `O(1)` amortized `push`.
|
||||
///
|
||||
/// `vec![x; n]`, `vec![a, b, c, d]`, and `Vec::with_capacity(n)`, will all
|
||||
/// produce a Vec with exactly the requested capacity. If `len() == capacity()`,
|
||||
/// (as is the case for the `vec!` macro), then a `Vec<T>` can be converted
|
||||
/// to and from a `Box<[T]>` without reallocating or moving the elements.
|
||||
///
|
||||
/// Vec will not specifically overwrite any data that is removed from it,
|
||||
/// but also won't specifically preserve it. Its uninitialized memory is
|
||||
/// scratch space that it may use however it wants. It will generally just do
|
||||
/// whatever is most efficient or otherwise easy to implement. Do not rely on
|
||||
/// removed data to be erased for security purposes. Even if you drop a Vec, its
|
||||
/// buffer may simply be reused by another Vec. Even if you zero a Vec's memory
|
||||
/// first, that may not actually happen because the optimizer does not consider
|
||||
/// this a side-effect that must be preserved.
|
||||
///
|
||||
/// Vec does not currently guarantee the order in which elements are dropped
|
||||
/// (the order has changed in the past, and may change again).
|
||||
///
|
||||
#[unsafe_no_drop_flag]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Vec<T> {
|
||||
|
|
|
|||
|
|
@ -367,6 +367,7 @@ pub enum ErrKind {
|
|||
ShiftRightWithOverflow,
|
||||
MissingStructField,
|
||||
NonConstPath,
|
||||
UnresolvedPath,
|
||||
ExpectedConstTuple,
|
||||
ExpectedConstStruct,
|
||||
TupleIndexOutOfBounds,
|
||||
|
|
@ -403,7 +404,8 @@ impl ConstEvalErr {
|
|||
ShiftLeftWithOverflow => "attempted left shift with overflow".into_cow(),
|
||||
ShiftRightWithOverflow => "attempted right shift with overflow".into_cow(),
|
||||
MissingStructField => "nonexistent struct field".into_cow(),
|
||||
NonConstPath => "non-constant path in constant expr".into_cow(),
|
||||
NonConstPath => "non-constant path in constant expression".into_cow(),
|
||||
UnresolvedPath => "unresolved path in constant expression".into_cow(),
|
||||
ExpectedConstTuple => "expected constant tuple".into_cow(),
|
||||
ExpectedConstStruct => "expected constant struct".into_cow(),
|
||||
TupleIndexOutOfBounds => "tuple index out of bounds".into_cow(),
|
||||
|
|
@ -895,7 +897,20 @@ pub fn eval_const_expr_partial<'tcx>(tcx: &ty::ctxt<'tcx>,
|
|||
}
|
||||
}
|
||||
hir::ExprPath(..) => {
|
||||
let opt_def = tcx.def_map.borrow().get(&e.id).map(|d| d.full_def());
|
||||
let opt_def = if let Some(def) = tcx.def_map.borrow().get(&e.id) {
|
||||
// After type-checking, def_map contains definition of the
|
||||
// item referred to by the path. During type-checking, it
|
||||
// can contain the raw output of path resolution, which
|
||||
// might be a partially resolved path.
|
||||
// FIXME: There's probably a better way to make sure we don't
|
||||
// panic here.
|
||||
if def.depth != 0 {
|
||||
signal!(e, UnresolvedPath);
|
||||
}
|
||||
Some(def.full_def())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let (const_expr, const_ty) = match opt_def {
|
||||
Some(def::DefConst(def_id)) => {
|
||||
if let Some(node_id) = tcx.map.as_local_node_id(def_id) {
|
||||
|
|
|
|||
|
|
@ -609,6 +609,29 @@ match Something::NotFoo {
|
|||
```
|
||||
"##,
|
||||
|
||||
E0422: r##"
|
||||
You are trying to use an identifier that is either undefined or not a
|
||||
struct. For instance:
|
||||
```
|
||||
fn main () {
|
||||
let x = Foo { x: 1, y: 2 };
|
||||
}
|
||||
```
|
||||
|
||||
In this case, `Foo` is undefined, so it inherently isn't anything, and
|
||||
definitely not a struct.
|
||||
|
||||
```
|
||||
fn main () {
|
||||
let foo = 1;
|
||||
let x = foo { x: 1, y: 2 };
|
||||
}
|
||||
```
|
||||
|
||||
In this case, `foo` is defined, but is not a struct, so Rust can't use
|
||||
it as one.
|
||||
"##,
|
||||
|
||||
E0423: r##"
|
||||
A `struct` variant name was used like a function name. Example of
|
||||
erroneous code:
|
||||
|
|
@ -888,7 +911,6 @@ register_diagnostics! {
|
|||
E0418, // is not an enum variant, struct or const
|
||||
E0420, // is not an associated const
|
||||
E0421, // unresolved associated const
|
||||
E0422, // does not name a structure
|
||||
E0427, // cannot use `ref` binding mode with ...
|
||||
E0429, // `self` imports are only allowed within a { } list
|
||||
E0434, // can't capture dynamic environment in a fn item
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ impl CString {
|
|||
/// Retakes ownership of a CString that was transferred to C.
|
||||
///
|
||||
/// The only appropriate argument is a pointer obtained by calling
|
||||
/// `into_ptr`. The length of the string will be recalculated
|
||||
/// `into_raw`. The length of the string will be recalculated
|
||||
/// using the pointer.
|
||||
#[unstable(feature = "cstr_memory2", reason = "recently added",
|
||||
issue = "27769")]
|
||||
|
|
@ -245,11 +245,11 @@ impl CString {
|
|||
/// Transfers ownership of the string to a C caller.
|
||||
///
|
||||
/// The pointer must be returned to Rust and reconstituted using
|
||||
/// `from_ptr` to be properly deallocated. Specifically, one
|
||||
/// `from_raw` to be properly deallocated. Specifically, one
|
||||
/// should *not* use the standard C `free` function to deallocate
|
||||
/// this string.
|
||||
///
|
||||
/// Failure to call `from_ptr` will lead to a memory leak.
|
||||
/// Failure to call `from_raw` will lead to a memory leak.
|
||||
#[stable(feature = "cstr_memory", since = "1.4.0")]
|
||||
pub fn into_raw(self) -> *mut libc::c_char {
|
||||
Box::into_raw(self.inner) as *mut libc::c_char
|
||||
|
|
|
|||
14
src/test/compile-fail/invalid-path-in-const.rs
Normal file
14
src/test/compile-fail/invalid-path-in-const.rs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// 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.
|
||||
|
||||
fn main() {
|
||||
fn f(a: [u8; u32::DOESNOTEXIST]) {}
|
||||
//~^ ERROR unresolved path in constant expression
|
||||
}
|
||||
19
src/test/run-pass/issue-25439.rs
Normal file
19
src/test/run-pass/issue-25439.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// 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.
|
||||
|
||||
struct Helper<'a, F: 'a>(&'a F);
|
||||
|
||||
fn fix<F>(f: F) -> i32 where F: Fn(Helper<F>, i32) -> i32 {
|
||||
f(Helper(&f), 8)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fix(|_, x| x);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue