Auto merge of #57542 - Centril:rollup, r=Centril
Rollup of 26 pull requests Successful merges: - #56425 (Redo the docs for Vec::set_len) - #56906 (Issue #56905) - #57042 (Don't call `FieldPlacement::count` when count is too large) - #57175 (Stabilize `let` bindings and destructuring in constants and const fn) - #57192 (Change std::error::Error trait documentation to talk about `source` instead of `cause`) - #57296 (Fixed the link to the ? operator) - #57368 (Use CMAKE_{C,CXX}_COMPILER_LAUNCHER for ccache) - #57400 (Rustdoc: update Source Serif Pro and replace Heuristica italic) - #57417 (rustdoc: use text-based doctest parsing if a macro is wrapping main) - #57433 (Add link destination for `read-ownership`) - #57434 (Remove `CrateNum::Invalid`.) - #57441 (Supporting backtrace for x86_64-fortanix-unknown-sgx.) - #57450 (actually take a slice in this example) - #57459 (Reference tracking issue for inherent associated types in diagnostic) - #57463 (docs: Fix some 'second-edition' links) - #57466 (Remove outdated comment) - #57493 (use structured suggestion when casting a reference) - #57498 (make note of one more normalization that Paths do) - #57499 (note that FromStr does not work for borrowed types) - #57505 (Remove submodule step from README) - #57510 (Add a profiles section to the manifest) - #57511 (Fix undefined behavior) - #57519 (Correct RELEASES.md for 1.32.0) - #57522 (don't unwrap unexpected tokens in `format!`) - #57530 (Fixing a typographical error.) - #57535 (Stabilise irrefutable if-let and while-let patterns) Failed merges: r? @ghost
This commit is contained in:
commit
d6525ef539
170 changed files with 1007 additions and 1493 deletions
|
|
@ -38,7 +38,6 @@ Read ["Installation"] from [The Book].
|
|||
3. Build and install:
|
||||
|
||||
```sh
|
||||
$ git submodule update --init --recursive --progress
|
||||
$ ./x.py build && sudo ./x.py install
|
||||
```
|
||||
|
||||
|
|
|
|||
24
RELEASES.md
24
RELEASES.md
|
|
@ -121,6 +121,12 @@ Stabilized APIs
|
|||
- [`i64::from_be_bytes`]
|
||||
- [`i64::from_le_bytes`]
|
||||
- [`i64::from_ne_bytes`]
|
||||
- [`i128::to_be_bytes`]
|
||||
- [`i128::to_le_bytes`]
|
||||
- [`i128::to_ne_bytes`]
|
||||
- [`i128::from_be_bytes`]
|
||||
- [`i128::from_le_bytes`]
|
||||
- [`i128::from_ne_bytes`]
|
||||
- [`isize::to_be_bytes`]
|
||||
- [`isize::to_le_bytes`]
|
||||
- [`isize::to_ne_bytes`]
|
||||
|
|
@ -151,6 +157,12 @@ Stabilized APIs
|
|||
- [`u64::from_be_bytes`]
|
||||
- [`u64::from_le_bytes`]
|
||||
- [`u64::from_ne_bytes`]
|
||||
- [`u128::to_be_bytes`]
|
||||
- [`u128::to_le_bytes`]
|
||||
- [`u128::to_ne_bytes`]
|
||||
- [`u128::from_be_bytes`]
|
||||
- [`u128::from_le_bytes`]
|
||||
- [`u128::from_ne_bytes`]
|
||||
- [`usize::to_be_bytes`]
|
||||
- [`usize::to_le_bytes`]
|
||||
- [`usize::to_ne_bytes`]
|
||||
|
|
@ -208,6 +220,12 @@ Compatibility Notes
|
|||
[`UnsafeCell::get`]: https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html#method.get
|
||||
[`slice::as_ptr`]: https://doc.rust-lang.org/std/primitive.slice.html#method.as_ptr
|
||||
[`char::is_ascii`]: https://doc.rust-lang.org/std/primitive.char.html#method.is_ascii
|
||||
[`i128::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_be_bytes
|
||||
[`i128::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_le_bytes
|
||||
[`i128::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.from_ne_bytes
|
||||
[`i128::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_be_bytes
|
||||
[`i128::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_le_bytes
|
||||
[`i128::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i128.html#method.to_ne_bytes
|
||||
[`i16::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_be_bytes
|
||||
[`i16::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_le_bytes
|
||||
[`i16::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.i16.html#method.from_ne_bytes
|
||||
|
|
@ -240,6 +258,12 @@ Compatibility Notes
|
|||
[`isize::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.isize.html#method.to_ne_bytes
|
||||
[`iter::empty`]: https://doc.rust-lang.org/std/iter/fn.empty.html
|
||||
[`str::as_ptr`]: https://doc.rust-lang.org/std/primitive.str.html#method.as_ptr
|
||||
[`u128::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_be_bytes
|
||||
[`u128::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_le_bytes
|
||||
[`u128::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.from_ne_bytes
|
||||
[`u128::to_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_be_bytes
|
||||
[`u128::to_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_le_bytes
|
||||
[`u128::to_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u128.html#method.to_ne_bytes
|
||||
[`u16::from_be_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_be_bytes
|
||||
[`u16::from_le_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_le_bytes
|
||||
[`u16::from_ne_bytes`]: https://doc.rust-lang.org/stable/std/primitive.u16.html#method.from_ne_bytes
|
||||
|
|
|
|||
|
|
@ -288,7 +288,7 @@
|
|||
#codegen-units-std = 1
|
||||
|
||||
# Whether or not debug assertions are enabled for the compiler and standard
|
||||
# library. Also enables compilation of debug! and trace! logging macros.
|
||||
# library.
|
||||
#debug-assertions = false
|
||||
|
||||
# Whether or not debuginfo is emitted
|
||||
|
|
|
|||
|
|
@ -346,15 +346,13 @@ fn configure_cmake(builder: &Builder,
|
|||
if builder.config.llvm_clang_cl.is_some() && target.contains("i686") {
|
||||
cfg.env("SCCACHE_EXTRA_ARGS", "-m32");
|
||||
}
|
||||
|
||||
// If ccache is configured we inform the build a little differently how
|
||||
// to invoke ccache while also invoking our compilers.
|
||||
} else if let Some(ref ccache) = builder.config.ccache {
|
||||
cfg.define("CMAKE_C_COMPILER", ccache)
|
||||
.define("CMAKE_C_COMPILER_ARG1", sanitize_cc(cc))
|
||||
.define("CMAKE_CXX_COMPILER", ccache)
|
||||
.define("CMAKE_CXX_COMPILER_ARG1", sanitize_cc(cxx));
|
||||
} else {
|
||||
// If ccache is configured we inform the build a little differently how
|
||||
// to invoke ccache while also invoking our compilers.
|
||||
if let Some(ref ccache) = builder.config.ccache {
|
||||
cfg.define("CMAKE_C_COMPILER_LAUNCHER", ccache)
|
||||
.define("CMAKE_CXX_COMPILER_LAUNCHER", ccache);
|
||||
}
|
||||
cfg.define("CMAKE_C_COMPILER", sanitize_cc(cc))
|
||||
.define("CMAKE_CXX_COMPILER", sanitize_cc(cxx));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
# `irrefutable_let_patterns`
|
||||
|
||||
The tracking issue for this feature is: [#44495]
|
||||
|
||||
[#44495]: https://github.com/rust-lang/rust/issues/44495
|
||||
|
||||
------------------------
|
||||
|
||||
This feature changes the way that "irrefutable patterns" are handled
|
||||
in the `if let` and `while let` forms. An *irrefutable pattern* is one
|
||||
that cannot fail to match -- for example, the `_` pattern matches any
|
||||
value, and hence it is "irrefutable". Without this feature, using an
|
||||
irrefutable pattern in an `if let` gives a hard error (since often
|
||||
this indicates programmer error). But when the feature is enabled, the
|
||||
error becomes a lint (since in some cases irrefutable patterns are
|
||||
expected). This means you can use `#[allow]` to silence the lint:
|
||||
|
||||
```rust
|
||||
#![feature(irrefutable_let_patterns)]
|
||||
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
fn main() {
|
||||
// These two examples used to be errors, but now they
|
||||
// trigger a lint (that is allowed):
|
||||
if let _ = 5 {}
|
||||
while let _ = 5 { break; }
|
||||
}
|
||||
```
|
||||
|
|
@ -738,53 +738,88 @@ impl<T> Vec<T> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the length of a vector.
|
||||
/// Forces the length of the vector to `new_len`.
|
||||
///
|
||||
/// This will explicitly set the size of the vector, without actually
|
||||
/// modifying its buffers, so it is up to the caller to ensure that the
|
||||
/// vector is actually the specified size.
|
||||
/// This is a low-level operation that maintains none of the normal
|
||||
/// invariants of the type. Normally changing the length of a vector
|
||||
/// is done using one of the safe operations instead, such as
|
||||
/// [`truncate`], [`resize`], [`extend`], or [`clear`].
|
||||
///
|
||||
/// [`truncate`]: #method.truncate
|
||||
/// [`resize`]: #method.resize
|
||||
/// [`extend`]: #method.extend-1
|
||||
/// [`clear`]: #method.clear
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - `new_len` must be less than or equal to [`capacity()`].
|
||||
/// - The elements at `old_len..new_len` must be initialized.
|
||||
///
|
||||
/// [`capacity()`]: #method.capacity
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::ptr;
|
||||
/// This method can be useful for situations in which the vector
|
||||
/// is serving as a buffer for other code, particularly over FFI:
|
||||
///
|
||||
/// let mut vec = vec!['r', 'u', 's', 't'];
|
||||
///
|
||||
/// unsafe {
|
||||
/// ptr::drop_in_place(&mut vec[3]);
|
||||
/// vec.set_len(3);
|
||||
/// ```no_run
|
||||
/// # #![allow(dead_code)]
|
||||
/// # // This is just a minimal skeleton for the doc example;
|
||||
/// # // don't use this as a starting point for a real library.
|
||||
/// # pub struct StreamWrapper { strm: *mut std::ffi::c_void }
|
||||
/// # const Z_OK: i32 = 0;
|
||||
/// # extern "C" {
|
||||
/// # fn deflateGetDictionary(
|
||||
/// # strm: *mut std::ffi::c_void,
|
||||
/// # dictionary: *mut u8,
|
||||
/// # dictLength: *mut usize,
|
||||
/// # ) -> i32;
|
||||
/// # }
|
||||
/// # impl StreamWrapper {
|
||||
/// pub fn get_dictionary(&self) -> Option<Vec<u8>> {
|
||||
/// // Per the FFI method's docs, "32768 bytes is always enough".
|
||||
/// let mut dict = Vec::with_capacity(32_768);
|
||||
/// let mut dict_length = 0;
|
||||
/// // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
|
||||
/// // 1. `dict_length` elements were initialized.
|
||||
/// // 2. `dict_length` <= the capacity (32_768)
|
||||
/// // which makes `set_len` safe to call.
|
||||
/// unsafe {
|
||||
/// // Make the FFI call...
|
||||
/// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
|
||||
/// if r == Z_OK {
|
||||
/// // ...and update the length to what was initialized.
|
||||
/// dict.set_len(dict_length);
|
||||
/// Some(dict)
|
||||
/// } else {
|
||||
/// None
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// assert_eq!(vec, ['r', 'u', 's']);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// In this example, there is a memory leak since the memory locations
|
||||
/// owned by the inner vectors were not freed prior to the `set_len` call:
|
||||
/// While the following example is sound, there is a memory leak since
|
||||
/// the inner vectors were not freed prior to the `set_len` call:
|
||||
///
|
||||
/// ```
|
||||
/// let mut vec = vec![vec![1, 0, 0],
|
||||
/// vec![0, 1, 0],
|
||||
/// vec![0, 0, 1]];
|
||||
/// // SAFETY:
|
||||
/// // 1. `old_len..0` is empty so no elements need to be initialized.
|
||||
/// // 2. `0 <= capacity` always holds whatever `capacity` is.
|
||||
/// unsafe {
|
||||
/// vec.set_len(0);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// In this example, the vector gets expanded from zero to four items
|
||||
/// without any memory allocations occurring, resulting in vector
|
||||
/// values of unallocated memory:
|
||||
///
|
||||
/// ```
|
||||
/// let mut vec: Vec<char> = Vec::new();
|
||||
///
|
||||
/// unsafe {
|
||||
/// vec.set_len(4);
|
||||
/// }
|
||||
/// ```
|
||||
/// Normally, here, one would use [`clear`] instead to correctly drop
|
||||
/// the contents and thus not leak memory.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub unsafe fn set_len(&mut self, len: usize) {
|
||||
self.len = len;
|
||||
pub unsafe fn set_len(&mut self, new_len: usize) {
|
||||
self.len = new_len;
|
||||
}
|
||||
|
||||
/// Removes an element from the vector and returns it.
|
||||
|
|
|
|||
|
|
@ -849,6 +849,7 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
|
|||
/// [valid]: ../ptr/index.html#safety
|
||||
/// [`Copy`]: ../marker/trait.Copy.html
|
||||
/// [`read`]: ./fn.read.html
|
||||
/// [read-ownership]: ./fn.read.html#ownership-of-the-returned-value
|
||||
///
|
||||
/// Just like in C, whether an operation is volatile has no bearing whatsoever
|
||||
/// on questions involving concurrent access from multiple threads. Volatile
|
||||
|
|
|
|||
|
|
@ -20,8 +20,7 @@ pub mod pattern;
|
|||
#[allow(missing_docs)]
|
||||
pub mod lossy;
|
||||
|
||||
/// A trait to abstract the idea of creating a new instance of a type from a
|
||||
/// string.
|
||||
/// Parse a value from a string
|
||||
///
|
||||
/// `FromStr`'s [`from_str`] method is often used implicitly, through
|
||||
/// [`str`]'s [`parse`] method. See [`parse`]'s documentation for examples.
|
||||
|
|
@ -30,6 +29,11 @@ pub mod lossy;
|
|||
/// [`str`]: ../../std/primitive.str.html
|
||||
/// [`parse`]: ../../std/primitive.str.html#method.parse
|
||||
///
|
||||
/// `FromStr` does not have a lifetime parameter, and so you can only parse types
|
||||
/// that do not contain a lifetime parameter themselves. In other words, you can
|
||||
/// parse an `i32` with `FromStr`, but not a `&i32`. You can parse a struct that
|
||||
/// contains an `i32`, but not one that contains an `&i32`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Basic implementation of `FromStr` on an example `Point` type:
|
||||
|
|
|
|||
|
|
@ -17,8 +17,6 @@ pub enum CrateNum {
|
|||
// FIXME(jseyfried): this is also used for custom derives until proc-macro crates get
|
||||
// `CrateNum`s.
|
||||
BuiltinMacros,
|
||||
/// A CrateNum value that indicates that something is wrong.
|
||||
Invalid,
|
||||
/// A special CrateNum that we use for the tcx.rcache when decoding from
|
||||
/// the incr. comp. cache.
|
||||
ReservedForIncrCompCache,
|
||||
|
|
@ -29,7 +27,6 @@ impl ::std::fmt::Debug for CrateNum {
|
|||
fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
|
||||
match self {
|
||||
CrateNum::Index(id) => write!(fmt, "crate{}", id.private),
|
||||
CrateNum::Invalid => write!(fmt, "invalid crate"),
|
||||
CrateNum::BuiltinMacros => write!(fmt, "builtin macros crate"),
|
||||
CrateNum::ReservedForIncrCompCache => write!(fmt, "crate for decoding incr comp cache"),
|
||||
}
|
||||
|
|
@ -90,7 +87,6 @@ impl fmt::Display for CrateNum {
|
|||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
CrateNum::Index(id) => fmt::Display::fmt(&id.private, f),
|
||||
CrateNum::Invalid => write!(f, "invalid crate"),
|
||||
CrateNum::BuiltinMacros => write!(f, "builtin macros crate"),
|
||||
CrateNum::ReservedForIncrCompCache => write!(f, "crate for decoding incr comp cache"),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ declare_lint! {
|
|||
|
||||
declare_lint! {
|
||||
pub IRREFUTABLE_LET_PATTERNS,
|
||||
Deny,
|
||||
Warn,
|
||||
"detects irrefutable patterns in if-let and while-let statements"
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -417,6 +417,12 @@ pub struct TypeckTables<'tcx> {
|
|||
/// All the existential types that are restricted to concrete types
|
||||
/// by this function
|
||||
pub concrete_existential_types: FxHashMap<DefId, Ty<'tcx>>,
|
||||
|
||||
/// Given the closure ID this map provides the list of UpvarIDs used by it.
|
||||
/// The upvarID contains the HIR node ID and it also contains the full path
|
||||
/// leading to the member of the struct or tuple that is used instead of the
|
||||
/// entire variable.
|
||||
pub upvar_list: ty::UpvarListMap,
|
||||
}
|
||||
|
||||
impl<'tcx> TypeckTables<'tcx> {
|
||||
|
|
@ -441,6 +447,7 @@ impl<'tcx> TypeckTables<'tcx> {
|
|||
tainted_by_errors: false,
|
||||
free_region_map: Default::default(),
|
||||
concrete_existential_types: Default::default(),
|
||||
upvar_list: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -741,6 +748,8 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
|
|||
tainted_by_errors,
|
||||
ref free_region_map,
|
||||
ref concrete_existential_types,
|
||||
ref upvar_list,
|
||||
|
||||
} = *self;
|
||||
|
||||
hcx.with_node_id_hashing_mode(NodeIdHashingMode::HashDefPath, |hcx| {
|
||||
|
|
@ -783,6 +792,7 @@ impl<'a, 'gcx> HashStable<StableHashingContext<'a>> for TypeckTables<'gcx> {
|
|||
tainted_by_errors.hash_stable(hcx, hasher);
|
||||
free_region_map.hash_stable(hcx, hasher);
|
||||
concrete_existential_types.hash_stable(hcx, hasher);
|
||||
upvar_list.hash_stable(hcx, hasher);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1842,7 +1842,11 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
|
|||
return Ok(None);
|
||||
}
|
||||
}
|
||||
if let FieldPlacement::Array { .. } = layout.fields {
|
||||
if let FieldPlacement::Array { count: original_64_bit_count, .. } = layout.fields {
|
||||
// rust-lang/rust#57038: avoid ICE within FieldPlacement::count when count too big
|
||||
if original_64_bit_count > usize::max_value() as u64 {
|
||||
return Err(LayoutError::SizeOverflow(layout.ty));
|
||||
}
|
||||
if layout.fields.count() > 0 {
|
||||
return self.find_niche(layout.field(self, 0)?);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -808,6 +808,7 @@ pub struct UpvarBorrow<'tcx> {
|
|||
pub region: ty::Region<'tcx>,
|
||||
}
|
||||
|
||||
pub type UpvarListMap = FxHashMap<DefId, Vec<UpvarId>>;
|
||||
pub type UpvarCaptureMap<'tcx> = FxHashMap<UpvarId, UpvarCapture<'tcx>>;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use hair::cx::Cx;
|
|||
use hair::{LintLevel, BindingMode, PatternKind};
|
||||
use rustc::hir;
|
||||
use rustc::hir::Node;
|
||||
use rustc::hir::def_id::{DefId, LocalDefId};
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::middle::region;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::{MutVisitor, TyContext};
|
||||
|
|
@ -640,21 +640,29 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
|||
let arguments: Vec<_> = arguments.collect();
|
||||
|
||||
let tcx = hir.tcx();
|
||||
let span = tcx.hir().span(fn_id);
|
||||
let tcx_hir = tcx.hir();
|
||||
let span = tcx_hir.span(fn_id);
|
||||
|
||||
let hir_tables = hir.tables();
|
||||
let fn_def_id = tcx_hir.local_def_id(fn_id);
|
||||
|
||||
// Gather the upvars of a closure, if any.
|
||||
let upvar_decls: Vec<_> = tcx.with_freevars(fn_id, |freevars| {
|
||||
freevars.iter().map(|fv| {
|
||||
let var_id = fv.var_id();
|
||||
let var_hir_id = tcx.hir().node_to_hir_id(var_id);
|
||||
let closure_expr_id = tcx.hir().local_def_id(fn_id);
|
||||
let capture = hir.tables().upvar_capture(ty::UpvarId {
|
||||
var_path: ty::UpvarPath {hir_id: var_hir_id},
|
||||
closure_expr_id: LocalDefId::from_def_id(closure_expr_id),
|
||||
});
|
||||
// In analyze_closure() in upvar.rs we gathered a list of upvars used by a
|
||||
// closure and we stored in a map called upvar_list in TypeckTables indexed
|
||||
// with the closure's DefId. Here, we run through that vec of UpvarIds for
|
||||
// the given closure and use the necessary information to create UpvarDecl.
|
||||
let upvar_decls: Vec<_> = hir_tables
|
||||
.upvar_list
|
||||
.get(&fn_def_id)
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.map(|upvar_id| {
|
||||
let var_hir_id = upvar_id.var_path.hir_id;
|
||||
let var_node_id = tcx_hir.hir_to_node_id(var_hir_id);
|
||||
let capture = hir_tables.upvar_capture(*upvar_id);
|
||||
let by_ref = match capture {
|
||||
ty::UpvarCapture::ByValue => false,
|
||||
ty::UpvarCapture::ByRef(..) => true
|
||||
ty::UpvarCapture::ByRef(..) => true,
|
||||
};
|
||||
let mut decl = UpvarDecl {
|
||||
debug_name: keywords::Invalid.name(),
|
||||
|
|
@ -662,10 +670,9 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
|||
by_ref,
|
||||
mutability: Mutability::Not,
|
||||
};
|
||||
if let Some(Node::Binding(pat)) = tcx.hir().find(var_id) {
|
||||
if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) {
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
|
||||
decl.debug_name = ident.name;
|
||||
|
||||
if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
|
||||
if bm == ty::BindByValue(hir::MutMutable) {
|
||||
decl.mutability = Mutability::Mut;
|
||||
|
|
@ -678,8 +685,8 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
|||
}
|
||||
}
|
||||
decl
|
||||
}).collect()
|
||||
});
|
||||
})
|
||||
.collect();
|
||||
|
||||
let mut builder = Builder::new(hir,
|
||||
span,
|
||||
|
|
@ -689,7 +696,6 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
|||
return_ty_span,
|
||||
upvar_decls);
|
||||
|
||||
let fn_def_id = tcx.hir().local_def_id(fn_id);
|
||||
let call_site_scope = region::Scope {
|
||||
id: body.value.hir_id.local_id,
|
||||
data: region::ScopeData::CallSite
|
||||
|
|
@ -732,7 +738,7 @@ fn construct_fn<'a, 'gcx, 'tcx, A>(hir: Cx<'a, 'gcx, 'tcx>,
|
|||
// RustCall pseudo-ABI untuples the last argument.
|
||||
spread_arg = Some(Local::new(arguments.len()));
|
||||
}
|
||||
let closure_expr_id = tcx.hir().local_def_id(fn_id);
|
||||
let closure_expr_id = tcx_hir.local_def_id(fn_id);
|
||||
info!("fn_id {:?} has attrs {:?}", closure_expr_id,
|
||||
tcx.get_attrs(closure_expr_id));
|
||||
|
||||
|
|
|
|||
|
|
@ -325,11 +325,13 @@ match Some(42) {
|
|||
"##,
|
||||
|
||||
E0162: r##"
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
An if-let pattern attempts to match the pattern, and enters the body if the
|
||||
match was successful. If the match is irrefutable (when it cannot fail to
|
||||
match), use a regular `let`-binding instead. For instance:
|
||||
|
||||
```compile_fail,E0162
|
||||
```compile_pass
|
||||
struct Irrefutable(i32);
|
||||
let irr = Irrefutable(0);
|
||||
|
||||
|
|
@ -352,11 +354,13 @@ println!("{}", x);
|
|||
"##,
|
||||
|
||||
E0165: r##"
|
||||
#### Note: this error code is no longer emitted by the compiler.
|
||||
|
||||
A while-let pattern attempts to match the pattern, and enters the body if the
|
||||
match was successful. If the match is irrefutable (when it cannot fail to
|
||||
match), use a regular `let`-binding inside a `loop` instead. For instance:
|
||||
|
||||
```compile_fail,E0165
|
||||
```compile_pass,no_run
|
||||
struct Irrefutable(i32);
|
||||
let irr = Irrefutable(0);
|
||||
|
||||
|
|
@ -2334,7 +2338,7 @@ local variable that already exists, and hence no temporary is created.
|
|||
Temporaries are not always dropped at the end of the enclosing
|
||||
statement. In simple cases where the `&` expression is immediately
|
||||
stored into a variable, the compiler will automatically extend
|
||||
the lifetime of the temporary until the end of the enclosinb
|
||||
the lifetime of the temporary until the end of the enclosing
|
||||
block. Therefore, an alternative way to fix the original
|
||||
program is to write `let tmp = &foo()` and not `let tmp = foo()`:
|
||||
|
||||
|
|
|
|||
|
|
@ -350,7 +350,6 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
|||
{
|
||||
let mut seen = Matrix::empty();
|
||||
let mut catchall = None;
|
||||
let mut printed_if_let_err = false;
|
||||
for (arm_index, &(ref pats, guard)) in arms.iter().enumerate() {
|
||||
for &(pat, hir_pat) in pats {
|
||||
let v = smallvec![pat];
|
||||
|
|
@ -359,27 +358,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
|||
NotUseful => {
|
||||
match source {
|
||||
hir::MatchSource::IfLetDesugar { .. } => {
|
||||
if cx.tcx.features().irrefutable_let_patterns {
|
||||
cx.tcx.lint_node(
|
||||
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
||||
hir_pat.id, pat.span,
|
||||
"irrefutable if-let pattern");
|
||||
} else {
|
||||
if printed_if_let_err {
|
||||
// we already printed an irrefutable if-let pattern error.
|
||||
// We don't want two, that's just confusing.
|
||||
} else {
|
||||
// find the first arm pattern so we can use its span
|
||||
let &(ref first_arm_pats, _) = &arms[0];
|
||||
let first_pat = &first_arm_pats[0];
|
||||
let span = first_pat.0.span;
|
||||
struct_span_err!(cx.tcx.sess, span, E0162,
|
||||
"irrefutable if-let pattern")
|
||||
.span_label(span, "irrefutable pattern")
|
||||
.emit();
|
||||
printed_if_let_err = true;
|
||||
}
|
||||
}
|
||||
cx.tcx.lint_node(
|
||||
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
||||
hir_pat.id,
|
||||
pat.span,
|
||||
"irrefutable if-let pattern",
|
||||
);
|
||||
}
|
||||
|
||||
hir::MatchSource::WhileLetDesugar => {
|
||||
|
|
@ -394,21 +378,12 @@ fn check_arms<'a, 'tcx>(cx: &mut MatchCheckCtxt<'a, 'tcx>,
|
|||
},
|
||||
// The arm with the wildcard pattern.
|
||||
1 => {
|
||||
if cx.tcx.features().irrefutable_let_patterns {
|
||||
cx.tcx.lint_node(
|
||||
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
||||
hir_pat.id, pat.span,
|
||||
"irrefutable while-let pattern");
|
||||
} else {
|
||||
// find the first arm pattern so we can use its span
|
||||
let &(ref first_arm_pats, _) = &arms[0];
|
||||
let first_pat = &first_arm_pats[0];
|
||||
let span = first_pat.0.span;
|
||||
struct_span_err!(cx.tcx.sess, span, E0165,
|
||||
"irrefutable while-let pattern")
|
||||
.span_label(span, "irrefutable pattern")
|
||||
.emit();
|
||||
}
|
||||
cx.tcx.lint_node(
|
||||
lint::builtin::IRREFUTABLE_LET_PATTERNS,
|
||||
hir_pat.id,
|
||||
pat.span,
|
||||
"irrefutable while-let pattern",
|
||||
);
|
||||
},
|
||||
_ => bug!(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext, NonMutatingUs
|
|||
use rustc::middle::lang_items;
|
||||
use rustc::session::config::nightly_options;
|
||||
use syntax::ast::LitKind;
|
||||
use syntax::feature_gate::{UnstableFeatures, feature_err, emit_feature_err, GateIssue};
|
||||
use syntax::feature_gate::{UnstableFeatures, emit_feature_err, GateIssue};
|
||||
use syntax_pos::{Span, DUMMY_SP};
|
||||
|
||||
use std::fmt;
|
||||
|
|
@ -104,7 +104,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
|
|||
param_env: ty::ParamEnv<'tcx>,
|
||||
local_qualif: IndexVec<Local, Option<Qualif>>,
|
||||
qualif: Qualif,
|
||||
const_fn_arg_vars: BitSet<Local>,
|
||||
temp_promotion_state: IndexVec<Local, TempState>,
|
||||
promotion_candidates: Vec<Candidate>
|
||||
}
|
||||
|
|
@ -139,7 +138,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
|||
param_env,
|
||||
local_qualif,
|
||||
qualif: Qualif::empty(),
|
||||
const_fn_arg_vars: BitSet::new_empty(mir.local_decls.len()),
|
||||
temp_promotion_state: temps,
|
||||
promotion_candidates: vec![]
|
||||
}
|
||||
|
|
@ -168,26 +166,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Error about extra statements in a constant.
|
||||
fn statement_like(&mut self) {
|
||||
self.add(Qualif::NOT_CONST);
|
||||
if self.mode != Mode::Fn {
|
||||
let mut err = feature_err(
|
||||
&self.tcx.sess.parse_sess,
|
||||
"const_let",
|
||||
self.span,
|
||||
GateIssue::Language,
|
||||
&format!("statements in {}s are unstable", self.mode),
|
||||
);
|
||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note("Blocks in constants may only contain items (such as constant, function \
|
||||
definition, etc...) and a tail expression.");
|
||||
err.help("To avoid it, you have to replace the non-item object.");
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
/// Add the given qualification to self.qualif.
|
||||
fn add(&mut self, qualif: Qualif) {
|
||||
self.qualif = self.qualif | qualif;
|
||||
|
|
@ -233,80 +211,46 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
|||
return;
|
||||
}
|
||||
|
||||
if self.tcx.features().const_let {
|
||||
let mut dest = dest;
|
||||
let index = loop {
|
||||
match dest {
|
||||
// with `const_let` active, we treat all locals equal
|
||||
Place::Local(index) => break *index,
|
||||
// projections are transparent for assignments
|
||||
// we qualify the entire destination at once, even if just a field would have
|
||||
// stricter qualification
|
||||
Place::Projection(proj) => {
|
||||
// Catch more errors in the destination. `visit_place` also checks various
|
||||
// projection rules like union field access and raw pointer deref
|
||||
self.visit_place(
|
||||
dest,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||
location
|
||||
);
|
||||
dest = &proj.base;
|
||||
},
|
||||
Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"),
|
||||
Place::Static(..) => {
|
||||
// Catch more errors in the destination. `visit_place` also checks that we
|
||||
// do not try to access statics from constants or try to mutate statics
|
||||
self.visit_place(
|
||||
dest,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||
location
|
||||
);
|
||||
return;
|
||||
}
|
||||
let mut dest = dest;
|
||||
let index = loop {
|
||||
match dest {
|
||||
// We treat all locals equal in constants
|
||||
Place::Local(index) => break *index,
|
||||
// projections are transparent for assignments
|
||||
// we qualify the entire destination at once, even if just a field would have
|
||||
// stricter qualification
|
||||
Place::Projection(proj) => {
|
||||
// Catch more errors in the destination. `visit_place` also checks various
|
||||
// projection rules like union field access and raw pointer deref
|
||||
self.visit_place(
|
||||
dest,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||
location
|
||||
);
|
||||
dest = &proj.base;
|
||||
},
|
||||
Place::Promoted(..) => bug!("promoteds don't exist yet during promotion"),
|
||||
Place::Static(..) => {
|
||||
// Catch more errors in the destination. `visit_place` also checks that we
|
||||
// do not try to access statics from constants or try to mutate statics
|
||||
self.visit_place(
|
||||
dest,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||
location
|
||||
);
|
||||
return;
|
||||
}
|
||||
};
|
||||
debug!("store to var {:?}", index);
|
||||
match &mut self.local_qualif[index] {
|
||||
// this is overly restrictive, because even full assignments do not clear the qualif
|
||||
// While we could special case full assignments, this would be inconsistent with
|
||||
// aggregates where we overwrite all fields via assignments, which would not get
|
||||
// that feature.
|
||||
Some(ref mut qualif) => *qualif = *qualif | self.qualif,
|
||||
// insert new qualification
|
||||
qualif @ None => *qualif = Some(self.qualif),
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
match *dest {
|
||||
Place::Local(index) if self.mir.local_kind(index) == LocalKind::Temp ||
|
||||
self.mir.local_kind(index) == LocalKind::ReturnPointer => {
|
||||
debug!("store to {:?} (temp or return pointer)", index);
|
||||
store(&mut self.local_qualif[index])
|
||||
}
|
||||
|
||||
Place::Projection(box Projection {
|
||||
base: Place::Local(index),
|
||||
elem: ProjectionElem::Deref
|
||||
}) if self.mir.local_kind(index) == LocalKind::Temp
|
||||
&& self.mir.local_decls[index].ty.is_box()
|
||||
&& self.local_qualif[index].map_or(false, |qualif| {
|
||||
qualif.contains(Qualif::NOT_CONST)
|
||||
}) => {
|
||||
// Part of `box expr`, we should've errored
|
||||
// already for the Box allocation Rvalue.
|
||||
}
|
||||
|
||||
// This must be an explicit assignment.
|
||||
_ => {
|
||||
// Catch more errors in the destination.
|
||||
self.visit_place(
|
||||
dest,
|
||||
PlaceContext::MutatingUse(MutatingUseContext::Store),
|
||||
location
|
||||
);
|
||||
self.statement_like();
|
||||
}
|
||||
};
|
||||
debug!("store to var {:?}", index);
|
||||
match &mut self.local_qualif[index] {
|
||||
// this is overly restrictive, because even full assignments do not clear the qualif
|
||||
// While we could special case full assignments, this would be inconsistent with
|
||||
// aggregates where we overwrite all fields via assignments, which would not get
|
||||
// that feature.
|
||||
Some(ref mut qualif) => *qualif = *qualif | self.qualif,
|
||||
// insert new qualification
|
||||
qualif @ None => *qualif = Some(self.qualif),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -347,45 +291,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
|
|||
TerminatorKind::FalseUnwind { .. } => None,
|
||||
|
||||
TerminatorKind::Return => {
|
||||
if !self.tcx.features().const_let {
|
||||
// Check for unused values. This usually means
|
||||
// there are extra statements in the AST.
|
||||
for temp in mir.temps_iter() {
|
||||
if self.local_qualif[temp].is_none() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let state = self.temp_promotion_state[temp];
|
||||
if let TempState::Defined { location, uses: 0 } = state {
|
||||
let data = &mir[location.block];
|
||||
let stmt_idx = location.statement_index;
|
||||
|
||||
// Get the span for the initialization.
|
||||
let source_info = if stmt_idx < data.statements.len() {
|
||||
data.statements[stmt_idx].source_info
|
||||
} else {
|
||||
data.terminator().source_info
|
||||
};
|
||||
self.span = source_info.span;
|
||||
|
||||
// Treat this as a statement in the AST.
|
||||
self.statement_like();
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure there are no extra unassigned variables.
|
||||
self.qualif = Qualif::NOT_CONST;
|
||||
for index in mir.vars_iter() {
|
||||
if !self.const_fn_arg_vars.contains(index) {
|
||||
debug!("unassigned variable {:?}", index);
|
||||
self.assign(&Place::Local(index), Location {
|
||||
block: bb,
|
||||
statement_index: usize::MAX,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
@ -454,12 +359,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||
LocalKind::ReturnPointer => {
|
||||
self.not_const();
|
||||
}
|
||||
LocalKind::Var if !self.tcx.features().const_let => {
|
||||
if self.mode != Mode::Fn {
|
||||
emit_feature_err(&self.tcx.sess.parse_sess, "const_let",
|
||||
self.span, GateIssue::Language,
|
||||
&format!("let bindings in {}s are unstable",self.mode));
|
||||
}
|
||||
LocalKind::Var if self.mode == Mode::Fn => {
|
||||
self.add(Qualif::NOT_CONST);
|
||||
}
|
||||
LocalKind::Var |
|
||||
|
|
@ -569,6 +469,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
ProjectionElem::ConstantIndex {..} |
|
||||
ProjectionElem::Subslice {..} |
|
||||
ProjectionElem::Field(..) |
|
||||
ProjectionElem::Index(_) => {
|
||||
let base_ty = proj.base.ty(this.mir, this.tcx).to_ty(this.tcx);
|
||||
|
|
@ -598,8 +500,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||
this.qualif.restrict(ty, this.tcx, this.param_env);
|
||||
}
|
||||
|
||||
ProjectionElem::ConstantIndex {..} |
|
||||
ProjectionElem::Subslice {..} |
|
||||
ProjectionElem::Downcast(..) => {
|
||||
this.not_const()
|
||||
}
|
||||
|
|
@ -1168,46 +1068,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
|
|||
debug!("visit_assign: dest={:?} rvalue={:?} location={:?}", dest, rvalue, location);
|
||||
self.visit_rvalue(rvalue, location);
|
||||
|
||||
// Check the allowed const fn argument forms.
|
||||
if let (Mode::ConstFn, &Place::Local(index)) = (self.mode, dest) {
|
||||
if self.mir.local_kind(index) == LocalKind::Var &&
|
||||
self.const_fn_arg_vars.insert(index) &&
|
||||
!self.tcx.features().const_let {
|
||||
// Direct use of an argument is permitted.
|
||||
match *rvalue {
|
||||
Rvalue::Use(Operand::Copy(Place::Local(local))) |
|
||||
Rvalue::Use(Operand::Move(Place::Local(local))) => {
|
||||
if self.mir.local_kind(local) == LocalKind::Arg {
|
||||
return;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
// Avoid a generic error for other uses of arguments.
|
||||
if self.qualif.contains(Qualif::FN_ARGUMENT) {
|
||||
let decl = &self.mir.local_decls[index];
|
||||
let mut err = feature_err(
|
||||
&self.tcx.sess.parse_sess,
|
||||
"const_let",
|
||||
decl.source_info.span,
|
||||
GateIssue::Language,
|
||||
"arguments of constant functions can only be immutable by-value bindings"
|
||||
);
|
||||
if self.tcx.sess.teach(&err.get_code().unwrap()) {
|
||||
err.note("Constant functions are not allowed to mutate anything. Thus, \
|
||||
binding to an argument with a mutable pattern is not allowed.");
|
||||
err.note("Remove any mutable bindings from the argument list to fix this \
|
||||
error. In case you need to mutate the argument, try lazily \
|
||||
initializing a global variable instead of using a const fn, or \
|
||||
refactoring the code to a functional style to avoid mutation if \
|
||||
possible.");
|
||||
}
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.assign(dest, location);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,12 +65,6 @@ pub fn is_min_const_fn(
|
|||
}
|
||||
}
|
||||
|
||||
for local in mir.vars_iter() {
|
||||
return Err((
|
||||
mir.local_decls[local].source_info.span,
|
||||
"local variables in const fn are unstable".into(),
|
||||
));
|
||||
}
|
||||
for local in &mir.local_decls {
|
||||
check_ty(tcx, local.ty, local.source_info.span)?;
|
||||
}
|
||||
|
|
@ -147,7 +141,7 @@ fn check_rvalue(
|
|||
check_operand(tcx, mir, operand, span)
|
||||
}
|
||||
Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) => {
|
||||
check_place(tcx, mir, place, span, PlaceMode::Read)
|
||||
check_place(tcx, mir, place, span)
|
||||
}
|
||||
Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
|
||||
use rustc::ty::cast::CastTy;
|
||||
|
|
@ -213,11 +207,6 @@ fn check_rvalue(
|
|||
}
|
||||
}
|
||||
|
||||
enum PlaceMode {
|
||||
Assign,
|
||||
Read,
|
||||
}
|
||||
|
||||
fn check_statement(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &'a Mir<'tcx>,
|
||||
|
|
@ -226,11 +215,11 @@ fn check_statement(
|
|||
let span = statement.source_info.span;
|
||||
match &statement.kind {
|
||||
StatementKind::Assign(place, rval) => {
|
||||
check_place(tcx, mir, place, span, PlaceMode::Assign)?;
|
||||
check_place(tcx, mir, place, span)?;
|
||||
check_rvalue(tcx, mir, rval, span)
|
||||
}
|
||||
|
||||
StatementKind::FakeRead(_, place) => check_place(tcx, mir, place, span, PlaceMode::Read),
|
||||
StatementKind::FakeRead(_, place) => check_place(tcx, mir, place, span),
|
||||
|
||||
// just an assignment
|
||||
StatementKind::SetDiscriminant { .. } => Ok(()),
|
||||
|
|
@ -256,7 +245,7 @@ fn check_operand(
|
|||
) -> McfResult {
|
||||
match operand {
|
||||
Operand::Move(place) | Operand::Copy(place) => {
|
||||
check_place(tcx, mir, place, span, PlaceMode::Read)
|
||||
check_place(tcx, mir, place, span)
|
||||
}
|
||||
Operand::Constant(_) => Ok(()),
|
||||
}
|
||||
|
|
@ -267,29 +256,17 @@ fn check_place(
|
|||
mir: &'a Mir<'tcx>,
|
||||
place: &Place<'tcx>,
|
||||
span: Span,
|
||||
mode: PlaceMode,
|
||||
) -> McfResult {
|
||||
match place {
|
||||
Place::Local(l) => match mode {
|
||||
PlaceMode::Assign => match mir.local_kind(*l) {
|
||||
LocalKind::Temp | LocalKind::ReturnPointer => Ok(()),
|
||||
LocalKind::Arg | LocalKind::Var => {
|
||||
Err((span, "assignments in const fn are unstable".into()))
|
||||
}
|
||||
},
|
||||
PlaceMode::Read => Ok(()),
|
||||
},
|
||||
Place::Local(_) => Ok(()),
|
||||
// promoteds are always fine, they are essentially constants
|
||||
Place::Promoted(_) => Ok(()),
|
||||
Place::Static(_) => Err((span, "cannot access `static` items in const fn".into())),
|
||||
Place::Projection(proj) => {
|
||||
match proj.elem {
|
||||
| ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. }
|
||||
| ProjectionElem::Deref | ProjectionElem::Field(..) | ProjectionElem::Index(_) => {
|
||||
check_place(tcx, mir, &proj.base, span, mode)
|
||||
}
|
||||
// slice patterns are unstable
|
||||
| ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
|
||||
return Err((span, "slice patterns in const fn are unstable".into()))
|
||||
check_place(tcx, mir, &proj.base, span)
|
||||
}
|
||||
| ProjectionElem::Downcast(..) => {
|
||||
Err((span, "`match` or `if let` in `const fn` is unstable".into()))
|
||||
|
|
@ -311,10 +288,10 @@ fn check_terminator(
|
|||
| TerminatorKind::Resume => Ok(()),
|
||||
|
||||
TerminatorKind::Drop { location, .. } => {
|
||||
check_place(tcx, mir, location, span, PlaceMode::Read)
|
||||
check_place(tcx, mir, location, span)
|
||||
}
|
||||
TerminatorKind::DropAndReplace { location, value, .. } => {
|
||||
check_place(tcx, mir, location, span, PlaceMode::Read)?;
|
||||
check_place(tcx, mir, location, span)?;
|
||||
check_operand(tcx, mir, value, span)
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -438,8 +438,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||
}
|
||||
for predicate in &generics.where_clause.predicates {
|
||||
if let WherePredicate::EqPredicate(ref predicate) = *predicate {
|
||||
self.err_handler().span_err(predicate.span, "equality constraints are not yet \
|
||||
supported in where clauses (#20041)");
|
||||
self.err_handler()
|
||||
.span_err(predicate.span, "equality constraints are not yet \
|
||||
supported in where clauses (see #20041)");
|
||||
}
|
||||
}
|
||||
visit::walk_generics(self, generics)
|
||||
|
|
|
|||
|
|
@ -213,8 +213,14 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
|
|||
fcx.ty_to_string(self.expr_ty),
|
||||
cast_ty));
|
||||
if let Ok(snippet) = fcx.sess().source_map().span_to_snippet(self.expr.span) {
|
||||
err.span_help(self.expr.span,
|
||||
&format!("did you mean `*{}`?", snippet));
|
||||
err.span_suggestion_with_applicability(
|
||||
self.expr.span,
|
||||
"dereference the expression",
|
||||
format!("*{}", snippet),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else {
|
||||
err.span_help(self.expr.span, "dereference the expression with `*`");
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,14 +122,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
};
|
||||
|
||||
self.tcx.with_freevars(closure_node_id, |freevars| {
|
||||
let mut freevar_list: Vec<ty::UpvarId> = Vec::with_capacity(freevars.len());
|
||||
for freevar in freevars {
|
||||
let upvar_id = ty::UpvarId {
|
||||
var_path: ty::UpvarPath {
|
||||
hir_id : self.tcx.hir().node_to_hir_id(freevar.var_id()),
|
||||
hir_id: self.tcx.hir().node_to_hir_id(freevar.var_id()),
|
||||
},
|
||||
closure_expr_id: LocalDefId::from_def_id(closure_def_id),
|
||||
};
|
||||
debug!("seed upvar_id {:?}", upvar_id);
|
||||
// Adding the upvar Id to the list of Upvars, which will be added
|
||||
// to the map for the closure at the end of the for loop.
|
||||
freevar_list.push(upvar_id);
|
||||
|
||||
let capture_kind = match capture_clause {
|
||||
hir::CaptureByValue => ty::UpvarCapture::ByValue,
|
||||
|
|
@ -149,6 +153,15 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
.upvar_capture_map
|
||||
.insert(upvar_id, capture_kind);
|
||||
}
|
||||
// Add the vector of freevars to the map keyed with the closure id.
|
||||
// This gives us an easier access to them without having to call
|
||||
// with_freevars again..
|
||||
if !freevar_list.is_empty() {
|
||||
self.tables
|
||||
.borrow_mut()
|
||||
.upvar_list
|
||||
.insert(closure_def_id, freevar_list);
|
||||
}
|
||||
});
|
||||
|
||||
let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
|
||||
|
|
@ -166,7 +179,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
self.param_env,
|
||||
region_scope_tree,
|
||||
&self.tables.borrow(),
|
||||
).consume_body(body);
|
||||
)
|
||||
.consume_body(body);
|
||||
|
||||
if let Some(closure_substs) = infer_kind {
|
||||
// Unify the (as yet unbound) type variable in the closure
|
||||
|
|
@ -240,9 +254,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
let var_hir_id = tcx.hir().node_to_hir_id(var_node_id);
|
||||
let freevar_ty = self.node_ty(var_hir_id);
|
||||
let upvar_id = ty::UpvarId {
|
||||
var_path: ty::UpvarPath {
|
||||
hir_id: var_hir_id,
|
||||
},
|
||||
var_path: ty::UpvarPath { hir_id: var_hir_id },
|
||||
closure_expr_id: LocalDefId::from_def_id(closure_def_index),
|
||||
};
|
||||
let capture = self.tables.borrow().upvar_capture(upvar_id);
|
||||
|
|
@ -262,7 +274,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
},
|
||||
),
|
||||
}
|
||||
}).collect()
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,15 @@ use syntax_pos::Span;
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// Entry point
|
||||
|
||||
// During type inference, partially inferred types are
|
||||
// represented using Type variables (ty::Infer). These don't appear in
|
||||
// the final TypeckTables since all of the types should have been
|
||||
// inferred once typeck_tables_of is done.
|
||||
// When type inference is running however, having to update the typeck
|
||||
// tables every time a new type is inferred would be unreasonably slow,
|
||||
// so instead all of the replacement happens at the end in
|
||||
// resolve_type_vars_in_body, which creates a new TypeTables which
|
||||
// doesn't contain any inference types.
|
||||
impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn resolve_type_vars_in_body(&self, body: &'gcx hir::Body) -> &'gcx ty::TypeckTables<'gcx> {
|
||||
let item_id = self.tcx.hir().body_owner(body.id());
|
||||
|
|
@ -35,7 +44,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
wbcx.visit_node_id(arg.pat.span, arg.hir_id);
|
||||
}
|
||||
wbcx.visit_body(body);
|
||||
wbcx.visit_upvar_borrow_map();
|
||||
wbcx.visit_upvar_capture_map();
|
||||
wbcx.visit_upvar_list_map();
|
||||
wbcx.visit_closures();
|
||||
wbcx.visit_liberated_fn_sigs();
|
||||
wbcx.visit_fru_field_types();
|
||||
|
|
@ -291,7 +301,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'gcx> for WritebackCx<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
||||
fn visit_upvar_borrow_map(&mut self) {
|
||||
fn visit_upvar_capture_map(&mut self) {
|
||||
for (upvar_id, upvar_capture) in self.fcx.tables.borrow().upvar_capture_map.iter() {
|
||||
let new_upvar_capture = match *upvar_capture {
|
||||
ty::UpvarCapture::ByValue => ty::UpvarCapture::ByValue,
|
||||
|
|
@ -314,6 +324,21 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Runs through the function context's upvar list map and adds the same to
|
||||
/// the TypeckTables. upvarlist is a hashmap of the list of upvars referred
|
||||
/// to in a closure..
|
||||
fn visit_upvar_list_map(&mut self) {
|
||||
for (closure_def_id, upvar_list) in self.fcx.tables.borrow().upvar_list.iter() {
|
||||
debug!(
|
||||
"UpvarIDs captured by closure {:?} are: {:?}",
|
||||
closure_def_id, upvar_list
|
||||
);
|
||||
self.tables
|
||||
.upvar_list
|
||||
.insert(*closure_def_id, upvar_list.to_vec());
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_closures(&mut self) {
|
||||
let fcx_tables = self.fcx.tables.borrow();
|
||||
debug_assert_eq!(fcx_tables.local_id_root, self.tables.local_id_root);
|
||||
|
|
|
|||
|
|
@ -1108,7 +1108,7 @@ fn report_assoc_ty_on_inherent_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span:
|
|||
tcx.sess,
|
||||
span,
|
||||
E0202,
|
||||
"associated types are not allowed in inherent impls"
|
||||
"associated types are not yet supported in inherent impls (see #8995)"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -893,14 +893,12 @@ themePicker.onblur = handleThemeButtonsBlur;
|
|||
static_files::fira_sans::MEDIUM)?;
|
||||
write(cx.dst.join("FiraSans-LICENSE.txt"),
|
||||
static_files::fira_sans::LICENSE)?;
|
||||
write(cx.dst.join("Heuristica-Italic.woff"),
|
||||
static_files::heuristica::ITALIC)?;
|
||||
write(cx.dst.join("Heuristica-LICENSE.txt"),
|
||||
static_files::heuristica::LICENSE)?;
|
||||
write(cx.dst.join("SourceSerifPro-Regular.woff"),
|
||||
write(cx.dst.join("SourceSerifPro-Regular.ttf.woff"),
|
||||
static_files::source_serif_pro::REGULAR)?;
|
||||
write(cx.dst.join("SourceSerifPro-Bold.woff"),
|
||||
write(cx.dst.join("SourceSerifPro-Bold.ttf.woff"),
|
||||
static_files::source_serif_pro::BOLD)?;
|
||||
write(cx.dst.join("SourceSerifPro-It.ttf.woff"),
|
||||
static_files::source_serif_pro::ITALIC)?;
|
||||
write(cx.dst.join("SourceSerifPro-LICENSE.txt"),
|
||||
static_files::source_serif_pro::LICENSE)?;
|
||||
write(cx.dst.join("SourceCodePro-Regular.woff"),
|
||||
|
|
|
|||
|
|
@ -12,21 +12,6 @@ included, and carry their own copyright notices and license terms:
|
|||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See FiraSans-LICENSE.txt.
|
||||
|
||||
* Heuristica (Heuristica-Italic.woff):
|
||||
|
||||
Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved.
|
||||
Utopia is either a registered trademark or trademark of Adobe Systems
|
||||
Incorporated in the United States and/or other countries. Used under
|
||||
license.
|
||||
|
||||
Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net
|
||||
|
||||
Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru),
|
||||
with Reserved Font Name Heuristica.
|
||||
|
||||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See Heuristica-LICENSE.txt.
|
||||
|
||||
* rustdoc.css, main.js, and playpen.js:
|
||||
|
||||
Copyright 2015 The Rust Developers.
|
||||
|
|
@ -47,7 +32,8 @@ included, and carry their own copyright notices and license terms:
|
|||
Licensed under the SIL Open Font License, Version 1.1.
|
||||
See SourceCodePro-LICENSE.txt.
|
||||
|
||||
* Source Serif Pro (SourceSerifPro-Regular.woff, SourceSerifPro-Bold.woff):
|
||||
* Source Serif Pro (SourceSerifPro-Regular.ttf.woff,
|
||||
SourceSerifPro-Bold.ttf.woff, SourceSerifPro-It.ttf.woff):
|
||||
|
||||
Copyright 2014 Adobe Systems Incorporated (http://www.adobe.com/), with
|
||||
Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,101 +0,0 @@
|
|||
Copyright 1989, 1991 Adobe Systems Incorporated. All rights reserved.
|
||||
Utopia is either a registered trademark or trademark of Adobe Systems
|
||||
Incorporated in the United States and/or other countries. Used under
|
||||
license.
|
||||
|
||||
Copyright 2006 Han The Thanh, Vntopia font family, http://vntex.sf.net
|
||||
|
||||
Copyright (c) 2008-2012, Andrey V. Panov (panov@canopus.iacp.dvo.ru),
|
||||
with Reserved Font Name Heuristica.
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||
BIN
src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff
Normal file
BIN
src/librustdoc/html/static/SourceSerifPro-Bold.ttf.woff
Normal file
Binary file not shown.
Binary file not shown.
BIN
src/librustdoc/html/static/SourceSerifPro-It.ttf.woff
Normal file
BIN
src/librustdoc/html/static/SourceSerifPro-It.ttf.woff
Normal file
Binary file not shown.
BIN
src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff
Normal file
BIN
src/librustdoc/html/static/SourceSerifPro-Regular.ttf.woff
Normal file
Binary file not shown.
Binary file not shown.
|
|
@ -12,25 +12,24 @@
|
|||
src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff');
|
||||
}
|
||||
|
||||
/* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license and
|
||||
* Heuristica-LICENSE.txt for the Heuristica license. */
|
||||
/* See SourceSerifPro-LICENSE.txt for the Source Serif Pro license. */
|
||||
@font-face {
|
||||
font-family: 'Source Serif Pro';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Source Serif Pro'), url("SourceSerifPro-Regular.woff") format('woff');
|
||||
src: local('Source Serif Pro'), url("SourceSerifPro-Regular.ttf.woff") format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Source Serif Pro';
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
src: url("Heuristica-Italic.woff") format('woff');
|
||||
src: local('Source Serif Pro Italic'), url("SourceSerifPro-It.ttf.woff") format('woff');
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Source Serif Pro';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.woff") format('woff');
|
||||
src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.ttf.woff") format('woff');
|
||||
}
|
||||
|
||||
/* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */
|
||||
|
|
|
|||
|
|
@ -73,22 +73,17 @@ pub mod fira_sans {
|
|||
pub static LICENSE: &'static [u8] = include_bytes!("static/FiraSans-LICENSE.txt");
|
||||
}
|
||||
|
||||
/// Files related to the Heuristica font.
|
||||
pub mod heuristica {
|
||||
/// The file `Heuristica-Italic.woff`, the Italic variant of the Heuristica font.
|
||||
pub static ITALIC: &'static [u8] = include_bytes!("static/Heuristica-Italic.woff");
|
||||
|
||||
/// The file `Heuristica-LICENSE.txt`, the license text for the Heuristica font.
|
||||
pub static LICENSE: &'static [u8] = include_bytes!("static/Heuristica-LICENSE.txt");
|
||||
}
|
||||
|
||||
/// Files related to the Source Serif Pro font.
|
||||
pub mod source_serif_pro {
|
||||
/// The file `SourceSerifPro-Regular.woff`, the Regular variant of the Source Serif Pro font.
|
||||
pub static REGULAR: &'static [u8] = include_bytes!("static/SourceSerifPro-Regular.woff");
|
||||
/// The file `SourceSerifPro-Regular.ttf.woff`, the Regular variant of the Source Serif Pro
|
||||
/// font.
|
||||
pub static REGULAR: &'static [u8] = include_bytes!("static/SourceSerifPro-Regular.ttf.woff");
|
||||
|
||||
/// The file `SourceSerifPro-Bold.woff`, the Bold variant of the Source Serif Pro font.
|
||||
pub static BOLD: &'static [u8] = include_bytes!("static/SourceSerifPro-Bold.woff");
|
||||
/// The file `SourceSerifPro-Bold.ttf.woff`, the Bold variant of the Source Serif Pro font.
|
||||
pub static BOLD: &'static [u8] = include_bytes!("static/SourceSerifPro-Bold.ttf.woff");
|
||||
|
||||
/// The file `SourceSerifPro-It.ttf.woff`, the Italic variant of the Source Serif Pro font.
|
||||
pub static ITALIC: &'static [u8] = include_bytes!("static/SourceSerifPro-It.ttf.woff");
|
||||
|
||||
/// The file `SourceSerifPro-LICENSE.txt`, the license text for the Source Serif Pro font.
|
||||
pub static LICENSE: &'static [u8] = include_bytes!("static/SourceSerifPro-LICENSE.txt");
|
||||
|
|
|
|||
|
|
@ -394,7 +394,7 @@ pub fn make_test(s: &str,
|
|||
|
||||
// Uses libsyntax to parse the doctest and find if there's a main fn and the extern
|
||||
// crate already is included.
|
||||
let (already_has_main, already_has_extern_crate) = crate::syntax::with_globals(|| {
|
||||
let (already_has_main, already_has_extern_crate, found_macro) = crate::syntax::with_globals(|| {
|
||||
use crate::syntax::{ast, parse::{self, ParseSess}, source_map::FilePathMapping};
|
||||
use crate::syntax_pos::FileName;
|
||||
use errors::emitter::EmitterWriter;
|
||||
|
|
@ -412,6 +412,7 @@ pub fn make_test(s: &str,
|
|||
|
||||
let mut found_main = false;
|
||||
let mut found_extern_crate = cratename.is_none();
|
||||
let mut found_macro = false;
|
||||
|
||||
let mut parser = match parse::maybe_new_parser_from_source_str(&sess, filename, source) {
|
||||
Ok(p) => p,
|
||||
|
|
@ -420,7 +421,7 @@ pub fn make_test(s: &str,
|
|||
err.cancel();
|
||||
}
|
||||
|
||||
return (found_main, found_extern_crate);
|
||||
return (found_main, found_extern_crate, found_macro);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -448,6 +449,12 @@ pub fn make_test(s: &str,
|
|||
}
|
||||
}
|
||||
|
||||
if !found_macro {
|
||||
if let ast::ItemKind::Mac(..) = item.node {
|
||||
found_macro = true;
|
||||
}
|
||||
}
|
||||
|
||||
if found_main && found_extern_crate {
|
||||
break;
|
||||
}
|
||||
|
|
@ -460,9 +467,28 @@ pub fn make_test(s: &str,
|
|||
}
|
||||
}
|
||||
|
||||
(found_main, found_extern_crate)
|
||||
(found_main, found_extern_crate, found_macro)
|
||||
});
|
||||
|
||||
// If a doctest's `fn main` is being masked by a wrapper macro, the parsing loop above won't
|
||||
// see it. In that case, run the old text-based scan to see if they at least have a main
|
||||
// function written inside a macro invocation. See
|
||||
// https://github.com/rust-lang/rust/issues/56898
|
||||
let already_has_main = if found_macro && !already_has_main {
|
||||
s.lines()
|
||||
.map(|line| {
|
||||
let comment = line.find("//");
|
||||
if let Some(comment_begins) = comment {
|
||||
&line[0..comment_begins]
|
||||
} else {
|
||||
line
|
||||
}
|
||||
})
|
||||
.any(|code| code.contains("fn main"))
|
||||
} else {
|
||||
already_has_main
|
||||
};
|
||||
|
||||
// Don't inject `extern crate std` because it's already injected by the
|
||||
// compiler.
|
||||
if !already_has_extern_crate && !opts.no_crate_inject && cratename != Some("std") {
|
||||
|
|
@ -1143,4 +1169,23 @@ assert_eq!(asdf::foo, 4);
|
|||
let output = make_test(input, Some("asdf"), false, &opts);
|
||||
assert_eq!(output, (expected, 3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn make_test_main_in_macro() {
|
||||
let opts = TestOptions::default();
|
||||
let input =
|
||||
"#[macro_use] extern crate my_crate;
|
||||
test_wrapper! {
|
||||
fn main() {}
|
||||
}";
|
||||
let expected =
|
||||
"#![allow(unused)]
|
||||
#[macro_use] extern crate my_crate;
|
||||
test_wrapper! {
|
||||
fn main() {}
|
||||
}".to_string();
|
||||
|
||||
let output = make_test(input, Some("my_crate"), false, &opts);
|
||||
assert_eq!(output, (expected, 1));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,17 +30,17 @@ use string;
|
|||
/// themselves through the [`Display`] and [`Debug`] traits, and may provide
|
||||
/// cause chain information:
|
||||
///
|
||||
/// The [`cause`] method is generally used when errors cross "abstraction
|
||||
/// boundaries", i.e., when a one module must report an error that is "caused"
|
||||
/// by an error from a lower-level module. This setup makes it possible for the
|
||||
/// high-level module to provide its own errors that do not commit to any
|
||||
/// particular implementation, but also reveal some of its implementation for
|
||||
/// debugging via [`cause`] chains.
|
||||
/// The [`source`] method is generally used when errors cross "abstraction
|
||||
/// boundaries". If one module must report an error that is caused by an error
|
||||
/// from a lower-level module, it can allow access to that error via the
|
||||
/// [`source`] method. This makes it possible for the high-level module to
|
||||
/// provide its own errors while also revealing some of the implementation for
|
||||
/// debugging via [`source`] chains.
|
||||
///
|
||||
/// [`Result<T, E>`]: ../result/enum.Result.html
|
||||
/// [`Display`]: ../fmt/trait.Display.html
|
||||
/// [`Debug`]: ../fmt/trait.Debug.html
|
||||
/// [`cause`]: trait.Error.html#method.cause
|
||||
/// [`source`]: trait.Error.html#method.source
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Error: Debug + Display {
|
||||
/// **This method is soft-deprecated.**
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@
|
|||
//! [`println!`]: ../macro.println.html
|
||||
//! [`Lines`]: struct.Lines.html
|
||||
//! [`io::Result`]: type.Result.html
|
||||
//! [`?` operator]: ../../book/first-edition/syntax-index.html
|
||||
//! [`?` operator]: ../../book/appendix-02-operators.html
|
||||
//! [`Read::read`]: trait.Read.html#tymethod.read
|
||||
//! [`Result`]: ../result/enum.Result.html
|
||||
//! [`.unwrap()`]: ../result/enum.Result.html#method.unwrap
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@
|
|||
#![feature(maybe_uninit)]
|
||||
#![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"),
|
||||
feature(global_asm, range_contains, slice_index_methods,
|
||||
decl_macro, coerce_unsized, sgx_platform))]
|
||||
decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))]
|
||||
|
||||
#![default_lib_allocator]
|
||||
|
||||
|
|
|
|||
|
|
@ -2203,6 +2203,8 @@ impl Path {
|
|||
/// `a/b` all have `a` and `b` as components, but `./a/b` starts with
|
||||
/// an additional [`CurDir`] component.
|
||||
///
|
||||
/// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
|
||||
///
|
||||
/// Note that no other normalization takes place; in particular, `a/c`
|
||||
/// and `a/b/../c` are distinct, to account for the possibility that `b`
|
||||
/// is a symbolic link (so its parent isn't `a`).
|
||||
|
|
|
|||
|
|
@ -550,7 +550,6 @@ mod prim_array { }
|
|||
#[doc(alias = "[")]
|
||||
#[doc(alias = "]")]
|
||||
#[doc(alias = "[]")]
|
||||
//
|
||||
/// A dynamically-sized view into a contiguous sequence, `[T]`.
|
||||
///
|
||||
/// *[See also the `std::slice` module](slice/index.html).*
|
||||
|
|
@ -572,11 +571,11 @@ mod prim_array { }
|
|||
/// points to:
|
||||
///
|
||||
/// ```
|
||||
/// let x = &mut [1, 2, 3];
|
||||
/// let mut x = [1, 2, 3];
|
||||
/// let x = &mut x[..]; // Take a full slice of `x`.
|
||||
/// x[1] = 7;
|
||||
/// assert_eq!(x, &[1, 7, 3]);
|
||||
/// ```
|
||||
///
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
mod prim_slice { }
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@ extern {
|
|||
// Do not remove inline: will result in relocation failure
|
||||
// For the same reason we use inline ASM here instead of an extern static to
|
||||
// locate the base
|
||||
/// Returns address at which current enclave is loaded.
|
||||
#[inline(always)]
|
||||
fn image_base() -> u64 {
|
||||
#[unstable(feature = "sgx_platform", issue = "56975")]
|
||||
pub fn image_base() -> u64 {
|
||||
let base;
|
||||
unsafe { asm!("lea IMAGE_BASE(%rip),$0":"=r"(base)) };
|
||||
base
|
||||
|
|
|
|||
|
|
@ -1,21 +1,90 @@
|
|||
use io;
|
||||
use sys::unsupported;
|
||||
use error::Error;
|
||||
use libc;
|
||||
use sys_common::backtrace::Frame;
|
||||
use unwind as uw;
|
||||
use sys::sgx::abi::mem::image_base;
|
||||
|
||||
pub struct BacktraceContext;
|
||||
|
||||
pub fn unwind_backtrace(_frames: &mut [Frame])
|
||||
-> io::Result<(usize, BacktraceContext)>
|
||||
{
|
||||
unsupported()
|
||||
struct Context<'a> {
|
||||
idx: usize,
|
||||
frames: &'a mut [Frame],
|
||||
}
|
||||
|
||||
pub fn resolve_symname<F>(_frame: Frame,
|
||||
_callback: F,
|
||||
#[derive(Debug)]
|
||||
struct UnwindError(uw::_Unwind_Reason_Code);
|
||||
|
||||
impl Error for UnwindError {
|
||||
fn description(&self) -> &'static str {
|
||||
"unexpected return value while unwinding"
|
||||
}
|
||||
}
|
||||
|
||||
impl ::fmt::Display for UnwindError {
|
||||
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
|
||||
write!(f, "{}: {:?}", self.description(), self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)] // this function call can be skipped it when tracing.
|
||||
pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
|
||||
let mut cx = Context { idx: 0, frames };
|
||||
let result_unwind =
|
||||
unsafe { uw::_Unwind_Backtrace(trace_fn, &mut cx as *mut Context as *mut libc::c_void) };
|
||||
// See libunwind:src/unwind/Backtrace.c for the return values.
|
||||
// No, there is no doc.
|
||||
let res = match result_unwind {
|
||||
// These return codes seem to be benign and need to be ignored for backtraces
|
||||
// to show up properly on all tested platforms.
|
||||
uw::_URC_END_OF_STACK | uw::_URC_FATAL_PHASE1_ERROR | uw::_URC_FAILURE => {
|
||||
Ok((cx.idx, BacktraceContext))
|
||||
}
|
||||
_ => Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
UnwindError(result_unwind),
|
||||
)),
|
||||
};
|
||||
res
|
||||
}
|
||||
|
||||
extern "C" fn trace_fn(
|
||||
ctx: *mut uw::_Unwind_Context,
|
||||
arg: *mut libc::c_void,
|
||||
) -> uw::_Unwind_Reason_Code {
|
||||
let cx = unsafe { &mut *(arg as *mut Context) };
|
||||
if cx.idx >= cx.frames.len() {
|
||||
return uw::_URC_NORMAL_STOP;
|
||||
}
|
||||
|
||||
let mut ip_before_insn = 0;
|
||||
let mut ip = unsafe { uw::_Unwind_GetIPInfo(ctx, &mut ip_before_insn) as *mut libc::c_void };
|
||||
if !ip.is_null() && ip_before_insn == 0 {
|
||||
// this is a non-signaling frame, so `ip` refers to the address
|
||||
// after the calling instruction. account for that.
|
||||
ip = (ip as usize - 1) as *mut _;
|
||||
}
|
||||
|
||||
let symaddr = unsafe { uw::_Unwind_FindEnclosingFunction(ip) };
|
||||
cx.frames[cx.idx] = Frame {
|
||||
symbol_addr: symaddr as *mut u8,
|
||||
exact_position: ip as *mut u8,
|
||||
inline_context: 0,
|
||||
};
|
||||
cx.idx += 1;
|
||||
|
||||
uw::_URC_NO_REASON
|
||||
}
|
||||
|
||||
// To reduce TCB size in Sgx enclave, we do not want to implement resolve_symname functionality.
|
||||
// Rather, we print the offset of the address here, which could be later mapped to correct function.
|
||||
pub fn resolve_symname<F>(frame: Frame,
|
||||
callback: F,
|
||||
_: &BacktraceContext) -> io::Result<()>
|
||||
where F: FnOnce(Option<&str>) -> io::Result<()>
|
||||
{
|
||||
unsupported()
|
||||
callback(Some(&format!("0x{:x}",
|
||||
(frame.symbol_addr.wrapping_offset_from(image_base() as _)))))
|
||||
}
|
||||
|
||||
pub fn foreach_symbol_fileline<F>(_: Frame,
|
||||
|
|
@ -23,5 +92,5 @@ pub fn foreach_symbol_fileline<F>(_: Frame,
|
|||
_: &BacktraceContext) -> io::Result<bool>
|
||||
where F: FnMut(&[u8], u32) -> io::Result<()>
|
||||
{
|
||||
unsupported()
|
||||
Ok(false)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result<Align16<[u8; 16]>, u32>
|
|||
: "={eax}"(error)
|
||||
: "{eax}"(ENCLU_EGETKEY),
|
||||
"{rbx}"(request),
|
||||
"{rcx}"(out.get_mut())
|
||||
"{rcx}"(out.as_mut_ptr())
|
||||
: "flags"
|
||||
);
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ pub fn ereport(
|
|||
: "{eax}"(ENCLU_EREPORT),
|
||||
"{rbx}"(targetinfo),
|
||||
"{rcx}"(reportdata),
|
||||
"{rdx}"(report.get_mut())
|
||||
"{rdx}"(report.as_mut_ptr())
|
||||
);
|
||||
|
||||
report.into_inner()
|
||||
|
|
|
|||
|
|
@ -193,9 +193,6 @@ declare_features! (
|
|||
// Allows the definition of `const` functions with some advanced features.
|
||||
(active, const_fn, "1.2.0", Some(24111), None),
|
||||
|
||||
// Allows let bindings and destructuring in `const` functions and constants.
|
||||
(active, const_let, "1.22.1", Some(48821), None),
|
||||
|
||||
// Allows accessing fields of unions inside `const` functions.
|
||||
(active, const_fn_union, "1.27.0", Some(51909), None),
|
||||
|
||||
|
|
@ -411,9 +408,6 @@ declare_features! (
|
|||
// `#[doc(alias = "...")]`
|
||||
(active, doc_alias, "1.27.0", Some(50146), None),
|
||||
|
||||
// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
|
||||
(active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
|
||||
|
||||
// inconsistent bounds in where clauses
|
||||
(active, trivial_bounds, "1.28.0", Some(48214), None),
|
||||
|
||||
|
|
@ -681,8 +675,14 @@ declare_features! (
|
|||
(accepted, underscore_imports, "1.33.0", Some(48216), None),
|
||||
// Allows `#[repr(packed(N))]` attribute on structs.
|
||||
(accepted, repr_packed, "1.33.0", Some(33158), None),
|
||||
// Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086).
|
||||
(accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None),
|
||||
// Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions.
|
||||
(accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None),
|
||||
// Allows let bindings, assignments and destructuring in `const` functions and constants.
|
||||
// As long as control flow is not implemented in const eval, `&&` and `||` may not be used
|
||||
// at the same time as let bindings.
|
||||
(accepted, const_let, "1.33.0", Some(48821), None),
|
||||
// `#[cfg_attr(predicate, multiple, attributes, here)]`
|
||||
(accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
|
||||
// Top level or-patterns (`p | q`) in `if let` and `while let`.
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ fn parse_args<'a>(
|
|||
};
|
||||
let name: &str = &ident.as_str();
|
||||
|
||||
p.expect(&token::Eq).unwrap();
|
||||
p.expect(&token::Eq)?;
|
||||
let e = p.parse_expr()?;
|
||||
if let Some(prev) = names.get(name) {
|
||||
ecx.struct_span_err(e.span, &format!("duplicate argument named `{}`", name))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(const_fn, const_let)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
const X : usize = 2;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
// run-pass
|
||||
#![feature(irrefutable_let_patterns)]
|
||||
|
||||
// must-compile-successfully-irrefutable_let_patterns_with_gate
|
||||
#[allow(irrefutable_let_patterns)]
|
||||
fn main() {
|
||||
if let _ = 5 {}
|
||||
|
||||
while let _ = 5 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
|
||||
#![feature(const_let)]
|
||||
|
||||
type Array = [u32; { let x = 2; 5 }];
|
||||
|
||||
pub fn main() {}
|
||||
pub fn main() {
|
||||
let _: Array = [0; 5];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
// run-pass
|
||||
#![allow(dead_code)]
|
||||
|
||||
#![feature(const_let)]
|
||||
|
||||
#[repr(u8)]
|
||||
enum Foo {
|
||||
Bar = { let x = 1; 3 }
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
pub fn main() {
|
||||
assert_eq!(3, Foo::Bar as u8);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
#![feature(const_fn, const_let)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
const fn x() {
|
||||
let t = true;
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
// https://github.com/rust-lang/rust/issues/48821
|
||||
|
||||
#![feature(const_fn, const_let)]
|
||||
|
||||
const fn foo(i: usize) -> usize {
|
||||
let x = i;
|
||||
x
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
// Test associated types are forbidden in inherent impls.
|
||||
// Test associated types are, until #8995 is implemented, forbidden in inherent impls.
|
||||
|
||||
struct Foo;
|
||||
|
||||
impl Foo {
|
||||
type Bar = isize; //~ERROR associated types are not allowed in inherent impls
|
||||
type Bar = isize; //~ERROR associated types are not yet supported in inherent impls (see #8995)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
error[E0202]: associated types are not allowed in inherent impls
|
||||
error[E0202]: associated types are not yet supported in inherent impls (see #8995)
|
||||
--> $DIR/assoc-inherent.rs:6:5
|
||||
|
|
||||
LL | type Bar = isize; //~ERROR associated types are not allowed in inherent impls
|
||||
LL | type Bar = isize; //~ERROR associated types are not yet supported in inherent impls (see #8995)
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
|
|
|||
|
|
@ -13,44 +13,80 @@ error[E0010]: allocations are not allowed in statics
|
|||
LL | static STATIC11: Box<MyOwned> = box MyOwned;
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:79:37
|
||||
|
|
||||
LL | static STATIC11: Box<MyOwned> = box MyOwned;
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/check-static-values-constraints.rs:89:32
|
||||
--> $DIR/check-static-values-constraints.rs:90:32
|
||||
|
|
||||
LL | field2: SafeEnum::Variant4("str".to_string())
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:94:5
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:95:5
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:95:9
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:99:6
|
||||
--> $DIR/check-static-values-constraints.rs:97:5
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:97:9
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:102:6
|
||||
|
|
||||
LL | &box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:102:10
|
||||
|
|
||||
LL | &box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:100:6
|
||||
--> $DIR/check-static-values-constraints.rs:104:6
|
||||
|
|
||||
LL | &box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:104:10
|
||||
|
|
||||
LL | &box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:106:5
|
||||
--> $DIR/check-static-values-constraints.rs:111:5
|
||||
|
|
||||
LL | box 3;
|
||||
| ^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:111:9
|
||||
|
|
||||
LL | box 3;
|
||||
| ^
|
||||
|
||||
error[E0507]: cannot move out of static item
|
||||
--> $DIR/check-static-values-constraints.rs:110:45
|
||||
--> $DIR/check-static-values-constraints.rs:116:45
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^
|
||||
|
|
@ -59,12 +95,18 @@ LL | let y = { static x: Box<isize> = box 3; x };
|
|||
| help: consider borrowing here: `&x`
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:110:38
|
||||
--> $DIR/check-static-values-constraints.rs:116:38
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^^^^^ allocation not allowed in statics
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:116:42
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^
|
||||
|
||||
Some errors occurred: E0010, E0015, E0493, E0507.
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
Some errors occurred: E0010, E0015, E0019, E0493, E0507.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ struct MyOwned;
|
|||
|
||||
static STATIC11: Box<MyOwned> = box MyOwned;
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~| ERROR static contains unimplemented expression type
|
||||
|
||||
static mut STATIC12: UnsafeStruct = UnsafeStruct;
|
||||
|
||||
|
|
@ -92,12 +93,16 @@ static mut STATIC14: SafeStruct = SafeStruct {
|
|||
|
||||
static STATIC15: &'static [Box<MyOwned>] = &[
|
||||
box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
];
|
||||
|
||||
static STATIC16: (&'static Box<MyOwned>, &'static Box<MyOwned>) = (
|
||||
&box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
&box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
);
|
||||
|
||||
static mut STATIC17: SafeEnum = SafeEnum::Variant1;
|
||||
|
|
@ -105,9 +110,11 @@ static mut STATIC17: SafeEnum = SafeEnum::Variant1;
|
|||
static STATIC19: Box<isize> =
|
||||
box 3;
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~| ERROR contains unimplemented expression
|
||||
|
||||
pub fn main() {
|
||||
let y = { static x: Box<isize> = box 3; x };
|
||||
//~^ ERROR allocations are not allowed in statics
|
||||
//~^^ ERROR cannot move out of static item
|
||||
//~| ERROR cannot move out of static item
|
||||
//~| ERROR contains unimplemented expression
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,55 +13,97 @@ error[E0010]: allocations are not allowed in statics
|
|||
LL | static STATIC11: Box<MyOwned> = box MyOwned;
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:79:37
|
||||
|
|
||||
LL | static STATIC11: Box<MyOwned> = box MyOwned;
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/check-static-values-constraints.rs:89:32
|
||||
--> $DIR/check-static-values-constraints.rs:90:32
|
||||
|
|
||||
LL | field2: SafeEnum::Variant4("str".to_string())
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:94:5
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:95:5
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:95:9
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:99:6
|
||||
--> $DIR/check-static-values-constraints.rs:97:5
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:97:9
|
||||
|
|
||||
LL | box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:102:6
|
||||
|
|
||||
LL | &box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:102:10
|
||||
|
|
||||
LL | &box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:100:6
|
||||
--> $DIR/check-static-values-constraints.rs:104:6
|
||||
|
|
||||
LL | &box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:104:10
|
||||
|
|
||||
LL | &box MyOwned, //~ ERROR allocations are not allowed in statics
|
||||
| ^^^^^^^
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:106:5
|
||||
--> $DIR/check-static-values-constraints.rs:111:5
|
||||
|
|
||||
LL | box 3;
|
||||
| ^^^^^ allocation not allowed in statics
|
||||
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:111:9
|
||||
|
|
||||
LL | box 3;
|
||||
| ^
|
||||
|
||||
error[E0507]: cannot move out of static item
|
||||
--> $DIR/check-static-values-constraints.rs:110:45
|
||||
--> $DIR/check-static-values-constraints.rs:116:45
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^ cannot move out of static item
|
||||
|
||||
error[E0010]: allocations are not allowed in statics
|
||||
--> $DIR/check-static-values-constraints.rs:110:38
|
||||
--> $DIR/check-static-values-constraints.rs:116:38
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^^^^^ allocation not allowed in statics
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/check-static-values-constraints.rs:116:42
|
||||
|
|
||||
LL | let y = { static x: Box<isize> = box 3; x };
|
||||
| ^
|
||||
|
||||
Some errors occurred: E0010, E0015, E0493, E0507.
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
Some errors occurred: E0010, E0015, E0019, E0493, E0507.
|
||||
For more information about an error, try `rustc --explain E0010`.
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
const A: usize = { 1; 2 };
|
||||
//~^ ERROR statements in constants are unstable
|
||||
|
||||
const B: usize = { { } 2 };
|
||||
//~^ ERROR statements in constants are unstable
|
||||
|
||||
macro_rules! foo {
|
||||
() => (()) //~ ERROR statements in constants are unstable
|
||||
}
|
||||
const C: usize = { foo!(); 2 };
|
||||
|
||||
const D: usize = { let x = 4; 2 };
|
||||
//~^ ERROR let bindings in constants are unstable
|
||||
//~| ERROR statements in constants are unstable
|
||||
//~| ERROR let bindings in constants are unstable
|
||||
//~| ERROR statements in constants are unstable
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-2.rs:1:20
|
||||
|
|
||||
LL | const A: usize = { 1; 2 };
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-2.rs:4:20
|
||||
|
|
||||
LL | const B: usize = { { } 2 };
|
||||
| ^^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-2.rs:8:12
|
||||
|
|
||||
LL | () => (()) //~ ERROR statements in constants are unstable
|
||||
| ^^
|
||||
LL | }
|
||||
LL | const C: usize = { foo!(); 2 };
|
||||
| ------- in this macro invocation
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-2.rs:12:28
|
||||
|
|
||||
LL | const D: usize = { let x = 4; 2 };
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-2.rs:12:28
|
||||
|
|
||||
LL | const D: usize = { let x = 4; 2 };
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-2.rs:12:1
|
||||
|
|
||||
LL | const D: usize = { let x = 4; 2 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-2.rs:12:1
|
||||
|
|
||||
LL | const D: usize = { let x = 4; 2 };
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
type Array = [u32; { let x = 2; 5 }];
|
||||
//~^ ERROR let bindings in constants are unstable
|
||||
//~| ERROR statements in constants are unstable
|
||||
//~| ERROR let bindings in constants are unstable
|
||||
//~| ERROR statements in constants are unstable
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
error[E0658]: let bindings in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-3.rs:1:31
|
||||
|
|
||||
LL | type Array = [u32; { let x = 2; 5 }];
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-3.rs:1:31
|
||||
|
|
||||
LL | type Array = [u32; { let x = 2; 5 }];
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-3.rs:1:20
|
||||
|
|
||||
LL | type Array = [u32; { let x = 2; 5 }];
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement-3.rs:1:20
|
||||
|
|
||||
LL | type Array = [u32; { let x = 2; 5 }];
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -1,9 +1,23 @@
|
|||
// compile-pass
|
||||
|
||||
enum Foo {
|
||||
Bar = { let x = 1; 3 }
|
||||
//~^ ERROR let bindings in constants are unstable
|
||||
//~| ERROR statements in constants are unstable
|
||||
//~| ERROR let bindings in constants are unstable
|
||||
//~| ERROR statements in constants are unstable
|
||||
}
|
||||
|
||||
|
||||
const A: usize = { 1; 2 };
|
||||
|
||||
const B: usize = { { } 2 };
|
||||
|
||||
macro_rules! foo {
|
||||
() => (())
|
||||
}
|
||||
|
||||
const C: usize = { foo!(); 2 };
|
||||
|
||||
const D: usize = { let x = 4; 2 };
|
||||
|
||||
type Array = [u32; { let x = 2; 5 }];
|
||||
type Array2 = [u32; { let mut x = 2; x = 3; x}];
|
||||
|
||||
pub fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
error[E0658]: let bindings in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement.rs:2:21
|
||||
|
|
||||
LL | Bar = { let x = 1; 3 }
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement.rs:2:21
|
||||
|
|
||||
LL | Bar = { let x = 1; 3 }
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement.rs:2:11
|
||||
|
|
||||
LL | Bar = { let x = 1; 3 }
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constants are unstable (see issue #48821)
|
||||
--> $DIR/const-block-non-item-statement.rs:2:11
|
||||
|
|
||||
LL | Bar = { let x = 1; 3 }
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -2,7 +2,6 @@
|
|||
// The test should never compile successfully
|
||||
|
||||
#![feature(const_raw_ptr_deref)]
|
||||
#![feature(const_let)]
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/assign-to-static-within-other-static-2.rs:17:5
|
||||
--> $DIR/assign-to-static-within-other-static-2.rs:16:5
|
||||
|
|
||||
LL | *FOO.0.get() = 5; //~ ERROR contains unimplemented expression type
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// The test should never compile successfully
|
||||
|
||||
#![feature(const_raw_ptr_deref)]
|
||||
#![feature(const_let)]
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: cannot mutate statics in the initializer of another static
|
||||
--> $DIR/assign-to-static-within-other-static.rs:11:5
|
||||
--> $DIR/assign-to-static-within-other-static.rs:10:5
|
||||
|
|
||||
LL | FOO = 5; //~ ERROR cannot mutate statics in the initializer of another static
|
||||
| ^^^^^^^
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(const_let)]
|
||||
|
||||
fn main() {}
|
||||
|
||||
struct FakeNeedsDrop;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/const_let.rs:15:55
|
||||
--> $DIR/const_let.rs:13:55
|
||||
|
|
||||
LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
|
||||
| ^
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/const_let.rs:19:35
|
||||
--> $DIR/const_let.rs:17:35
|
||||
|
|
||||
LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); };
|
||||
| ^
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(const_let)]
|
||||
|
||||
fn main() {
|
||||
// Tests the Collatz conjecture with an incorrect base case (0 instead of 1).
|
||||
// The value of `n` will loop indefinitely (4 - 2 - 1 - 4).
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/infinite_loop.rs:9:9
|
||||
--> $DIR/infinite_loop.rs:7:9
|
||||
|
|
||||
LL | / while n != 0 { //~ ERROR constant contains unimplemented expression type
|
||||
LL | | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
||||
|
|
@ -8,7 +8,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
warning: Constant evaluating a complex constant, this might take some time
|
||||
--> $DIR/infinite_loop.rs:6:18
|
||||
--> $DIR/infinite_loop.rs:4:18
|
||||
|
|
||||
LL | let _ = [(); {
|
||||
| __________________^
|
||||
|
|
@ -21,7 +21,7 @@ LL | | }];
|
|||
| |_____^
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/infinite_loop.rs:10:20
|
||||
--> $DIR/infinite_loop.rs:8:20
|
||||
|
|
||||
LL | n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
|
||||
| ^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(const_let)]
|
||||
|
||||
fn main() {
|
||||
let _ = [(); {
|
||||
//~^ WARNING Constant evaluating a complex constant, this might take some time
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/issue-52475.rs:8:9
|
||||
--> $DIR/issue-52475.rs:6:9
|
||||
|
|
||||
LL | / while n < 5 { //~ ERROR constant contains unimplemented expression type
|
||||
LL | | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed
|
||||
|
|
@ -8,7 +8,7 @@ LL | | }
|
|||
| |_________^
|
||||
|
||||
warning: Constant evaluating a complex constant, this might take some time
|
||||
--> $DIR/issue-52475.rs:4:18
|
||||
--> $DIR/issue-52475.rs:2:18
|
||||
|
|
||||
LL | let _ = [(); {
|
||||
| __________________^
|
||||
|
|
@ -21,7 +21,7 @@ LL | | }];
|
|||
| |_____^
|
||||
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $DIR/issue-52475.rs:9:17
|
||||
--> $DIR/issue-52475.rs:7:17
|
||||
|
|
||||
LL | n = (n + 1) % 5; //~ ERROR evaluation of constant value failed
|
||||
| ^^^^^^^^^^^ duplicate interpreter state observed here, const evaluation will never terminate
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// The test should never compile successfully
|
||||
|
||||
#![feature(const_raw_ptr_deref)]
|
||||
#![feature(const_let)]
|
||||
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
error[E0019]: static contains unimplemented expression type
|
||||
--> $DIR/mod-static-with-const-fn.rs:19:5
|
||||
--> $DIR/mod-static-with-const-fn.rs:18:5
|
||||
|
|
||||
LL | *FOO.0.get() = 5;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
--> $DIR/mod-static-with-const-fn.rs:22:5
|
||||
--> $DIR/mod-static-with-const-fn.rs:21:5
|
||||
|
|
||||
LL | foo();
|
||||
| ^^^^^
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(const_transmute,const_let)]
|
||||
#![feature(const_transmute)]
|
||||
#![allow(const_err)] // make sure we cannot allow away the errors tested here
|
||||
|
||||
use std::mem;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,7 @@
|
|||
// test that certain things are disallowed in constant functions
|
||||
// compile-pass
|
||||
|
||||
#![feature(const_fn)]
|
||||
|
||||
// no destructuring
|
||||
const fn i((
|
||||
a,
|
||||
//~^ ERROR arguments of constant functions can only be immutable by-value bindings
|
||||
b
|
||||
//~^ ERROR arguments of constant functions can only be immutable by-value bindings
|
||||
): (u32, u32)) -> u32 {
|
||||
const fn i((a, b): (u32, u32)) -> u32 {
|
||||
a + b
|
||||
//~^ ERROR let bindings in constant functions are unstable
|
||||
//~| ERROR let bindings in constant functions are unstable
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -1,35 +0,0 @@
|
|||
error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821)
|
||||
--> $DIR/const-fn-destructuring-arg.rs:7:13
|
||||
|
|
||||
LL | a,
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: arguments of constant functions can only be immutable by-value bindings (see issue #48821)
|
||||
--> $DIR/const-fn-destructuring-arg.rs:9:13
|
||||
|
|
||||
LL | b
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constant functions are unstable (see issue #48821)
|
||||
--> $DIR/const-fn-destructuring-arg.rs:12:5
|
||||
|
|
||||
LL | a + b
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constant functions are unstable (see issue #48821)
|
||||
--> $DIR/const-fn-destructuring-arg.rs:12:9
|
||||
|
|
||||
LL | a + b
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
|
@ -27,13 +27,9 @@ const fn get_Y_addr() -> &'static u32 {
|
|||
}
|
||||
|
||||
const fn get() -> u32 {
|
||||
let x = 22; //~ ERROR let bindings in constant functions are unstable
|
||||
//~^ ERROR statements in constant functions
|
||||
let y = 44; //~ ERROR let bindings in constant functions are unstable
|
||||
//~^ ERROR statements in constant functions
|
||||
let x = 22;
|
||||
let y = 44;
|
||||
x + y
|
||||
//~^ ERROR let bindings in constant functions are unstable
|
||||
//~| ERROR let bindings in constant functions are unstable
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
|
|
@ -16,55 +16,7 @@ error[E0013]: constant functions cannot refer to statics, use a constant instead
|
|||
LL | &Y
|
||||
| ^^
|
||||
|
||||
error[E0658]: let bindings in constant functions are unstable (see issue #48821)
|
||||
--> $DIR/const-fn-not-safe-for-const.rs:30:13
|
||||
|
|
||||
LL | let x = 22; //~ ERROR let bindings in constant functions are unstable
|
||||
| ^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
error[E0658]: statements in constant functions are unstable (see issue #48821)
|
||||
--> $DIR/const-fn-not-safe-for-const.rs:30:13
|
||||
|
|
||||
LL | let x = 22; //~ ERROR let bindings in constant functions are unstable
|
||||
| ^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constant functions are unstable (see issue #48821)
|
||||
--> $DIR/const-fn-not-safe-for-const.rs:32:13
|
||||
|
|
||||
LL | let y = 44; //~ ERROR let bindings in constant functions are unstable
|
||||
| ^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: statements in constant functions are unstable (see issue #48821)
|
||||
--> $DIR/const-fn-not-safe-for-const.rs:32:13
|
||||
|
|
||||
LL | let y = 44; //~ ERROR let bindings in constant functions are unstable
|
||||
| ^^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constant functions are unstable (see issue #48821)
|
||||
--> $DIR/const-fn-not-safe-for-const.rs:34:5
|
||||
|
|
||||
LL | x + y
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error[E0658]: let bindings in constant functions are unstable (see issue #48821)
|
||||
--> $DIR/const-fn-not-safe-for-const.rs:34:9
|
||||
|
|
||||
LL | x + y
|
||||
| ^
|
||||
|
|
||||
= help: add #![feature(const_let)] to the crate attributes to enable
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors occurred: E0013, E0015, E0658.
|
||||
Some errors occurred: E0013, E0015.
|
||||
For more information about an error, try `rustc --explain E0013`.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
// compile-pass
|
||||
|
||||
#![feature(const_let)]
|
||||
|
||||
struct S(i32);
|
||||
|
||||
const A: () = {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
// compile-pass
|
||||
|
||||
#![feature(const_let)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
pub struct AA {
|
||||
pub data: [u8; 10],
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
#![feature(const_let)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
struct S {
|
||||
|
|
@ -18,6 +17,15 @@ const FOO: S = {
|
|||
s
|
||||
};
|
||||
|
||||
type Array = [u32; {
|
||||
let mut x = 2;
|
||||
let y = &mut x;
|
||||
//~^ ERROR references in constants may only refer to immutable values
|
||||
*y = 42;
|
||||
//~^ ERROR constant contains unimplemented expression type
|
||||
*y
|
||||
}];
|
||||
|
||||
fn main() {
|
||||
assert_eq!(FOO.state, 3);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,28 @@
|
|||
error[E0019]: constant function contains unimplemented expression type
|
||||
--> $DIR/const_let_assign3.rs:10:9
|
||||
--> $DIR/const_let_assign3.rs:9:9
|
||||
|
|
||||
LL | self.state = x;
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0017]: references in constants may only refer to immutable values
|
||||
--> $DIR/const_let_assign3.rs:17:5
|
||||
--> $DIR/const_let_assign3.rs:16:5
|
||||
|
|
||||
LL | s.foo(3); //~ ERROR references in constants may only refer to immutable values
|
||||
| ^ constants require immutable values
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0017]: references in constants may only refer to immutable values
|
||||
--> $DIR/const_let_assign3.rs:22:13
|
||||
|
|
||||
LL | let y = &mut x;
|
||||
| ^^^^^^ constants require immutable values
|
||||
|
||||
error[E0019]: constant contains unimplemented expression type
|
||||
--> $DIR/const_let_assign3.rs:24:5
|
||||
|
|
||||
LL | *y = 42;
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
Some errors occurred: E0017, E0019.
|
||||
For more information about an error, try `rustc --explain E0017`.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(const_let, const_fn)]
|
||||
|
||||
// run-pass
|
||||
|
||||
struct Foo<T>(T);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// compile-pass
|
||||
|
||||
#![feature(const_let, const_fn)]
|
||||
#![feature(const_fn)]
|
||||
|
||||
struct Foo<T>(T);
|
||||
struct Bar<T> { x: T }
|
||||
|
|
|
|||
11
src/test/ui/consts/const_let_irrefutable.rs
Normal file
11
src/test/ui/consts/const_let_irrefutable.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// compile-pass
|
||||
|
||||
fn main() {}
|
||||
|
||||
const fn tup((a, b): (i32, i32)) -> i32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
const fn array([a, b]: [i32; 2]) -> i32 {
|
||||
a + b
|
||||
}
|
||||
5
src/test/ui/consts/const_let_refutable.rs
Normal file
5
src/test/ui/consts/const_let_refutable.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
fn main() {}
|
||||
|
||||
const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
|
||||
a + b
|
||||
}
|
||||
9
src/test/ui/consts/const_let_refutable.stderr
Normal file
9
src/test/ui/consts/const_let_refutable.stderr
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
error[E0005]: refutable pattern in function argument: `&[]` not covered
|
||||
--> $DIR/const_let_refutable.rs:3:16
|
||||
|
|
||||
LL | const fn slice([a, b]: &[i32]) -> i32 { //~ ERROR refutable pattern in function argument
|
||||
| ^^^^^^ pattern `&[]` not covered
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0005`.
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
#![feature(underscore_const_names, const_let)]
|
||||
#![feature(underscore_const_names)]
|
||||
|
||||
const _: bool = false && false;
|
||||
const _: bool = true && false;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
// https://github.com/rust-lang/rust/issues/55223
|
||||
|
||||
#![feature(const_let)]
|
||||
|
||||
union Foo<'a> {
|
||||
y: &'a (),
|
||||
long_live_the_unit: &'static (),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: any use of this value will cause an error
|
||||
--> $DIR/dangling-alloc-id-ice.rs:10:1
|
||||
--> $DIR/dangling-alloc-id-ice.rs:8:1
|
||||
|
|
||||
LL | / const FOO: &() = { //~ ERROR any use of this value will cause an error
|
||||
LL | | let y = ();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(const_let)]
|
||||
|
||||
const FOO: *const u32 = { //~ ERROR any use of this value will cause an error
|
||||
let x = 42;
|
||||
&x
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error: any use of this value will cause an error
|
||||
--> $DIR/dangling_raw_ptr.rs:3:1
|
||||
--> $DIR/dangling_raw_ptr.rs:1:1
|
||||
|
|
||||
LL | / const FOO: *const u32 = { //~ ERROR any use of this value will cause an error
|
||||
LL | | let x = 42;
|
||||
|
|
|
|||
|
|
@ -112,12 +112,6 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn
|
|||
LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: local variables in const fn are unstable
|
||||
--> $DIR/min_const_fn.rs:99:34
|
||||
|
|
||||
LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn
|
||||
| ^
|
||||
|
||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||
--> $DIR/min_const_fn.rs:100:44
|
||||
|
|
||||
|
|
@ -220,7 +214,7 @@ error: function pointers in const fn are unstable
|
|||
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 35 previous errors
|
||||
error: aborting due to 34 previous errors
|
||||
|
||||
Some errors occurred: E0493, E0515.
|
||||
For more information about an error, try `rustc --explain E0493`.
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize }
|
|||
const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
|
||||
//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
|
||||
const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
||||
const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn
|
||||
const fn foo30_6() -> bool { let x = true; x }
|
||||
const fn foo36(a: bool, b: bool) -> bool { a && b }
|
||||
//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
|
||||
const fn foo37(a: bool, b: bool) -> bool { a || b }
|
||||
|
|
|
|||
|
|
@ -112,12 +112,6 @@ error: `if`, `match`, `&&` and `||` are not stable in const fn
|
|||
LL | const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: local variables in const fn are unstable
|
||||
--> $DIR/min_const_fn.rs:99:34
|
||||
|
|
||||
LL | const fn foo30_6() -> bool { let x = true; x } //~ ERROR local variables in const fn
|
||||
| ^
|
||||
|
||||
error: `if`, `match`, `&&` and `||` are not stable in const fn
|
||||
--> $DIR/min_const_fn.rs:100:44
|
||||
|
|
||||
|
|
@ -208,6 +202,6 @@ error: function pointers in const fn are unstable
|
|||
LL | const fn no_fn_ptrs2() -> fn() { fn foo() {} foo }
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 35 previous errors
|
||||
error: aborting due to 34 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0493`.
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
const fn mutable_ref_in_const() -> u8 {
|
||||
let mut a = 0; //~ ERROR local variables in const fn
|
||||
let b = &mut a;
|
||||
let mut a = 0;
|
||||
let b = &mut a; //~ ERROR mutable references in const fn
|
||||
*b
|
||||
}
|
||||
|
||||
|
|
@ -8,8 +8,8 @@ struct X;
|
|||
|
||||
impl X {
|
||||
const fn inherent_mutable_ref_in_const() -> u8 {
|
||||
let mut a = 0; //~ ERROR local variables in const fn
|
||||
let b = &mut a;
|
||||
let mut a = 0;
|
||||
let b = &mut a; //~ ERROR mutable references in const fn
|
||||
*b
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
error: local variables in const fn are unstable
|
||||
--> $DIR/mutable_borrow.rs:2:9
|
||||
error: mutable references in const fn are unstable
|
||||
--> $DIR/mutable_borrow.rs:3:9
|
||||
|
|
||||
LL | let mut a = 0; //~ ERROR local variables in const fn
|
||||
| ^^^^^
|
||||
LL | let b = &mut a; //~ ERROR mutable references in const fn
|
||||
| ^
|
||||
|
||||
error: local variables in const fn are unstable
|
||||
--> $DIR/mutable_borrow.rs:11:13
|
||||
error: mutable references in const fn are unstable
|
||||
--> $DIR/mutable_borrow.rs:12:13
|
||||
|
|
||||
LL | let mut a = 0; //~ ERROR local variables in const fn
|
||||
| ^^^^^
|
||||
LL | let b = &mut a; //~ ERROR mutable references in const fn
|
||||
| ^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![feature(const_let)]
|
||||
|
||||
use std::cell::Cell;
|
||||
|
||||
const FOO: &(Cell<usize>, bool) = {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
error[E0492]: cannot borrow a constant which may contain interior mutability, create a static instead
|
||||
--> $DIR/partial_qualif.rs:8:5
|
||||
--> $DIR/partial_qualif.rs:6:5
|
||||
|
|
||||
LL | &{a} //~ ERROR cannot borrow a constant which may contain interior mutability
|
||||
| ^^^^
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue