1
Fork 0

Auto merge of #56215 - pietroalbini:rollup, r=pietroalbini

Rollup of 14 pull requests

Successful merges:

 - #56024 (Don't auto-inline const functions)
 - #56045 (Check arg/ret sizedness at ExprKind::Path)
 - #56072 (Stabilize macro_literal_matcher)
 - #56075 (Encode a custom "producers" section in wasm files)
 - #56100 (generator fields are not necessarily initialized)
 - #56101 (Incorporate `dyn` into more comments and docs.)
 - #56144 (Fix BTreeSet and BTreeMap gdb pretty-printers)
 - #56151 (Move a flaky process test out of libstd)
 - #56170 (Fix self profiler ICE on Windows)
 - #56176 (Panic setup msg)
 - #56204 (Suggest correct enum variant on typo)
 - #56207 (Stabilize the int_to_from_bytes feature)
 - #56210 (read_c_str should call the AllocationExtra hooks)
 - #56211 ([master] Forward-ports from beta)

Failed merges:

r? @ghost
This commit is contained in:
bors 2018-11-25 16:08:01 +00:00
commit 5bd451b265
65 changed files with 686 additions and 374 deletions

View file

@ -1,17 +0,0 @@
# `macro_literal_matcher`
The tracking issue for this feature is: [#35625]
The RFC is: [rfc#1576].
With this feature gate enabled, the [list of designators] gains one more entry:
* `literal`: a literal. Examples: 2, "string", 'c'
A `literal` may be followed by anything, similarly to the `ident` specifier.
[rfc#1576]: http://rust-lang.github.io/rfcs/1576-macros-literal-matcher.html
[#35625]: https://github.com/rust-lang/rust/issues/35625
[list of designators]: ../reference/macros-by-example.html
------------------------

View file

@ -80,8 +80,6 @@ fn main() {
}
```
However, the current implementation allows `MyTupleStruct(..)` to be unsized. This will be fixed in the future.
## By-value trait objects
With this feature, you can have by-value `self` arguments without `Self: Sized` bounds.

View file

@ -375,32 +375,6 @@ def extract_tail_head_ptr_and_cap_from_std_vecdeque(vec_val):
assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
return (tail, head, data_ptr, capacity)
def extract_length_and_ptr_from_std_btreeset(vec_val):
assert vec_val.type.get_type_kind() == TYPE_KIND_STD_BTREESET
map = vec_val.get_child_at_index(0)
root = map.get_child_at_index(0)
length = map.get_child_at_index(1).as_integer()
node = root.get_child_at_index(0)
ptr = node.get_child_at_index(0)
unique_ptr_val = ptr.get_child_at_index(0)
data_ptr = unique_ptr_val.get_child_at_index(0)
assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
return (length, data_ptr)
def extract_length_and_ptr_from_std_btreemap(vec_val):
assert vec_val.type.get_type_kind() == TYPE_KIND_STD_BTREEMAP
root = vec_val.get_child_at_index(0)
length = vec_val.get_child_at_index(1).as_integer()
node = root.get_child_at_index(0)
ptr = node.get_child_at_index(0)
unique_ptr_val = ptr.get_child_at_index(0)
data_ptr = unique_ptr_val.get_child_at_index(0)
assert data_ptr.type.get_dwarf_type_kind() == DWARF_TYPE_CODE_PTR
return (length, data_ptr)
def extract_length_and_ptr_from_slice(slice_val):
assert (slice_val.type.get_type_kind() == TYPE_KIND_SLICE or
slice_val.type.get_type_kind() == TYPE_KIND_STR_SLICE)

View file

@ -319,6 +319,32 @@ class RustStdVecDequePrinter(object):
yield (str(index), (gdb_ptr + ((tail + index) % cap)).dereference())
# Yield each key (and optionally value) from a BoxedNode.
def children_of_node(boxed_node, height, want_values):
ptr = boxed_node['ptr']['pointer']
# This is written oddly because we don't want to rely on the field name being `__0`.
node_ptr = ptr[ptr.type.fields()[0]]
if height > 0:
type_name = str(node_ptr.type.target()).replace('LeafNode', 'InternalNode')
node_type = gdb.lookup_type(type_name)
node_ptr = node_ptr.cast(node_type.pointer())
leaf = node_ptr['data']
else:
leaf = node_ptr.dereference()
keys = leaf['keys']['value']['value']
if want_values:
values = leaf['vals']['value']['value']
length = int(leaf['len'])
for i in xrange(0, length + 1):
if height > 0:
for child in children_of_node(node_ptr['edges'][i], height - 1, want_values):
yield child
if i < length:
if want_values:
yield (keys[i], values[i])
else:
yield keys[i]
class RustStdBTreeSetPrinter(object):
def __init__(self, val):
self.__val = val
@ -328,21 +354,16 @@ class RustStdBTreeSetPrinter(object):
return "array"
def to_string(self):
(length, data_ptr) = \
rustpp.extract_length_and_ptr_from_std_btreeset(self.__val)
return (self.__val.type.get_unqualified_type_name() +
("(len: %i)" % length))
("(len: %i)" % self.__val.get_wrapped_value()['map']['length']))
def children(self):
(length, data_ptr) = \
rustpp.extract_length_and_ptr_from_std_btreeset(self.__val)
leaf_node = GdbValue(data_ptr.get_wrapped_value().dereference())
maybe_uninit_keys = leaf_node.get_child_at_index(3)
manually_drop_keys = maybe_uninit_keys.get_child_at_index(1)
keys = manually_drop_keys.get_child_at_index(0)
gdb_ptr = keys.get_wrapped_value()
for index in xrange(length):
yield (str(index), gdb_ptr[index])
root = self.__val.get_wrapped_value()['map']['root']
node_ptr = root['node']
i = 0
for child in children_of_node(node_ptr, root['height'], False):
yield (str(i), child)
i = i + 1
class RustStdBTreeMapPrinter(object):
@ -354,26 +375,17 @@ class RustStdBTreeMapPrinter(object):
return "map"
def to_string(self):
(length, data_ptr) = \
rustpp.extract_length_and_ptr_from_std_btreemap(self.__val)
return (self.__val.type.get_unqualified_type_name() +
("(len: %i)" % length))
("(len: %i)" % self.__val.get_wrapped_value()['length']))
def children(self):
(length, data_ptr) = \
rustpp.extract_length_and_ptr_from_std_btreemap(self.__val)
leaf_node = GdbValue(data_ptr.get_wrapped_value().dereference())
maybe_uninit_keys = leaf_node.get_child_at_index(3)
manually_drop_keys = maybe_uninit_keys.get_child_at_index(1)
keys = manually_drop_keys.get_child_at_index(0)
keys_ptr = keys.get_wrapped_value()
maybe_uninit_vals = leaf_node.get_child_at_index(4)
manually_drop_vals = maybe_uninit_vals.get_child_at_index(1)
vals = manually_drop_vals.get_child_at_index(0)
vals_ptr = vals.get_wrapped_value()
for index in xrange(length):
yield (str(index), keys_ptr[index])
yield (str(index), vals_ptr[index])
root = self.__val.get_wrapped_value()['root']
node_ptr = root['node']
i = 0
for child in children_of_node(node_ptr, root['height'], True):
yield (str(i), child[0])
yield (str(i), child[1])
i = i + 1
class RustStdStringPrinter(object):

View file

@ -489,7 +489,7 @@ impl Box<dyn Any> {
/// ```
/// use std::any::Any;
///
/// fn print_if_string(value: Box<Any>) {
/// fn print_if_string(value: Box<dyn Any>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }
@ -523,7 +523,7 @@ impl Box<dyn Any + Send> {
/// ```
/// use std::any::Any;
///
/// fn print_if_string(value: Box<Any + Send>) {
/// fn print_if_string(value: Box<dyn Any + Send>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }
@ -618,10 +618,10 @@ impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {}
/// `FnBox` is a version of the `FnOnce` intended for use with boxed
/// closure objects. The idea is that where one would normally store a
/// `Box<FnOnce()>` in a data structure, you should use
/// `Box<FnBox()>`. The two traits behave essentially the same, except
/// `Box<dyn FnOnce()>` in a data structure, you should use
/// `Box<dyn FnBox()>`. The two traits behave essentially the same, except
/// that a `FnBox` closure can only be called if it is boxed. (Note
/// that `FnBox` may be deprecated in the future if `Box<FnOnce()>`
/// that `FnBox` may be deprecated in the future if `Box<dyn FnOnce()>`
/// closures become directly usable.)
///
/// # Examples
@ -629,7 +629,7 @@ impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {}
/// Here is a snippet of code which creates a hashmap full of boxed
/// once closures and then removes them one by one, calling each
/// closure as it is removed. Note that the type of the closures
/// stored in the map is `Box<FnBox() -> i32>` and not `Box<FnOnce()
/// stored in the map is `Box<dyn FnBox() -> i32>` and not `Box<dyn FnOnce()
/// -> i32>`.
///
/// ```
@ -638,8 +638,8 @@ impl<I: FusedIterator + ?Sized> FusedIterator for Box<I> {}
/// use std::boxed::FnBox;
/// use std::collections::HashMap;
///
/// fn make_map() -> HashMap<i32, Box<FnBox() -> i32>> {
/// let mut map: HashMap<i32, Box<FnBox() -> i32>> = HashMap::new();
/// fn make_map() -> HashMap<i32, Box<dyn FnBox() -> i32>> {
/// let mut map: HashMap<i32, Box<dyn FnBox() -> i32>> = HashMap::new();
/// map.insert(1, Box::new(|| 22));
/// map.insert(2, Box::new(|| 44));
/// map

View file

@ -633,7 +633,7 @@ impl<T: Clone> Rc<T> {
impl Rc<dyn Any> {
#[inline]
#[stable(feature = "rc_downcast", since = "1.29.0")]
/// Attempt to downcast the `Rc<Any>` to a concrete type.
/// Attempt to downcast the `Rc<dyn Any>` to a concrete type.
///
/// # Examples
///
@ -641,7 +641,7 @@ impl Rc<dyn Any> {
/// use std::any::Any;
/// use std::rc::Rc;
///
/// fn print_if_string(value: Rc<Any>) {
/// fn print_if_string(value: Rc<dyn Any>) {
/// if let Ok(string) = value.downcast::<String>() {
/// println!("String ({}): {}", string.len(), string);
/// }

View file

@ -1921,12 +1921,10 @@ big-endian (network) byte order.
# Examples
```
#![feature(int_to_from_bytes)]
let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
assert_eq!(bytes, ", $be_bytes, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
@ -1941,12 +1939,10 @@ little-endian byte order.
# Examples
```
#![feature(int_to_from_bytes)]
let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
assert_eq!(bytes, ", $le_bytes, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
@ -1969,8 +1965,6 @@ instead.
# Examples
```
#![feature(int_to_from_bytes)]
let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
assert_eq!(bytes, if cfg!(target_endian = \"big\") {
", $be_bytes, "
@ -1978,7 +1972,7 @@ assert_eq!(bytes, if cfg!(target_endian = \"big\") {
", $le_bytes, "
});
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
@ -1993,12 +1987,10 @@ big endian.
# Examples
```
#![feature(int_to_from_bytes)]
let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
assert_eq!(value, ", $swap_op, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
@ -2014,12 +2006,10 @@ little endian.
# Examples
```
#![feature(int_to_from_bytes)]
let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
assert_eq!(value, ", $swap_op, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
@ -2041,8 +2031,6 @@ appropriate instead.
# Examples
```
#![feature(int_to_from_bytes)]
let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
", $be_bytes, "
} else {
@ -2050,7 +2038,7 @@ let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"bi
});
assert_eq!(value, ", $swap_op, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
@ -3663,12 +3651,10 @@ big-endian (network) byte order.
# Examples
```
#![feature(int_to_from_bytes)]
let bytes = ", $swap_op, stringify!($SelfT), ".to_be_bytes();
assert_eq!(bytes, ", $be_bytes, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
@ -3683,12 +3669,10 @@ little-endian byte order.
# Examples
```
#![feature(int_to_from_bytes)]
let bytes = ", $swap_op, stringify!($SelfT), ".to_le_bytes();
assert_eq!(bytes, ", $le_bytes, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
@ -3711,8 +3695,6 @@ instead.
# Examples
```
#![feature(int_to_from_bytes)]
let bytes = ", $swap_op, stringify!($SelfT), ".to_ne_bytes();
assert_eq!(bytes, if cfg!(target_endian = \"big\") {
", $be_bytes, "
@ -3720,7 +3702,7 @@ assert_eq!(bytes, if cfg!(target_endian = \"big\") {
", $le_bytes, "
});
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
@ -3735,12 +3717,10 @@ big endian.
# Examples
```
#![feature(int_to_from_bytes)]
let value = ", stringify!($SelfT), "::from_be_bytes(", $be_bytes, ");
assert_eq!(value, ", $swap_op, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
@ -3756,12 +3736,10 @@ little endian.
# Examples
```
#![feature(int_to_from_bytes)]
let value = ", stringify!($SelfT), "::from_le_bytes(", $le_bytes, ");
assert_eq!(value, ", $swap_op, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
@ -3783,8 +3761,6 @@ appropriate instead.
# Examples
```
#![feature(int_to_from_bytes)]
let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"big\") {
", $be_bytes, "
} else {
@ -3792,7 +3768,7 @@ let value = ", stringify!($SelfT), "::from_ne_bytes(if cfg!(target_endian = \"bi
});
assert_eq!(value, ", $swap_op, ");
```"),
#[unstable(feature = "int_to_from_bytes", issue = "52963")]
#[stable(feature = "int_to_from_bytes", since = "1.32.0")]
#[rustc_const_unstable(feature = "const_int_conversion")]
#[inline]
pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {

View file

@ -21,7 +21,7 @@
/// The representation of a trait object like `&SomeTrait`.
///
/// This struct has the same layout as types like `&SomeTrait` and
/// `Box<AnotherTrait>`.
/// `Box<dyn AnotherTrait>`.
///
/// `TraitObject` is guaranteed to match layouts, but it is not the
/// type of trait objects (e.g. the fields are not directly accessible

View file

@ -172,10 +172,11 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
let offset = ptr.offset.bytes() as usize;
match self.bytes[offset..].iter().position(|&c| c == 0) {
Some(size) => {
let p1 = Size::from_bytes((size + 1) as u64);
self.check_relocations(cx, ptr, p1)?;
self.check_defined(ptr, p1)?;
Ok(&self.bytes[offset..offset + size])
let size_with_null = Size::from_bytes((size + 1) as u64);
// Go through `get_bytes` for checks and AllocationExtra hooks.
// We read the null, so we include it in the request, but we want it removed
// from the result!
Ok(&self.get_bytes(cx, ptr, size_with_null)?[..size])
}
None => err!(UnterminatedCString(ptr.erase_tag())),
}
@ -315,11 +316,9 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra<Tag>> Allocation<Tag, Extra> {
},
};
{
let endian = cx.data_layout().endian;
let dst = self.get_bytes_mut(cx, ptr, type_size)?;
write_target_uint(endian, dst, bytes).unwrap();
}
let endian = cx.data_layout().endian;
let dst = self.get_bytes_mut(cx, ptr, type_size)?;
write_target_uint(endian, dst, bytes).unwrap();
// See if we have to also write a relocation
match val {

View file

@ -2200,7 +2200,7 @@ pub enum CastKind {
/// "Unsize" -- convert a thin-or-fat pointer to a fat pointer.
/// codegen must figure out the details once full monomorphization
/// is known. For example, this could be used to cast from a
/// `&[i32;N]` to a `&[i32]`, or a `Box<T>` to a `Box<Trait>`
/// `&[i32;N]` to a `&[i32]`, or a `Box<T>` to a `Box<dyn Trait>`
/// (presuming `T: Trait`).
Unsize,
}

View file

@ -826,8 +826,10 @@ impl Session {
}
pub fn profiler<F: FnOnce(&mut SelfProfiler) -> ()>(&self, f: F) {
let mut profiler = self.self_profiling.borrow_mut();
f(&mut profiler);
if self.opts.debugging_opts.self_profile {
let mut profiler = self.self_profiling.borrow_mut();
f(&mut profiler);
}
}
pub fn print_profiler_results(&self) {

View file

@ -48,7 +48,7 @@ use ty::subst::Substs;
/// stored in `unsize` is `Foo<[i32]>`, we don't store any further detail about
/// the underlying conversions from `[i32; 4]` to `[i32]`.
///
/// 3. Coercing a `Box<T>` to `Box<Trait>` is an interesting special case. In
/// 3. Coercing a `Box<T>` to `Box<dyn Trait>` is an interesting special case. In
/// that case, we have the pointer we need coming in, so there are no
/// autoderefs, and no autoref. Instead we just do the `Unsize` transformation.
/// At some point, of course, `Box` should move out of the compiler, in which

View file

@ -173,10 +173,7 @@ impl<'tcx> InstanceDef<'tcx> {
// available to normal end-users.
return true
}
let codegen_fn_attrs = tcx.codegen_fn_attrs(self.def_id());
// need to use `is_const_fn_raw` since we don't really care if the user can use it as a
// const fn, just whether the function should be inlined
codegen_fn_attrs.requests_inline() || tcx.is_const_fn_raw(self.def_id())
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
}
}

View file

@ -303,7 +303,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
/// Same as applying struct_tail on `source` and `target`, but only
/// keeps going as long as the two types are instances of the same
/// structure definitions.
/// For `(Foo<Foo<T>>, Foo<Trait>)`, the result will be `(Foo<T>, Trait)`,
/// For `(Foo<Foo<T>>, Foo<dyn Trait>)`, the result will be `(Foo<T>, Trait)`,
/// whereas struct_tail produces `T`, and `Trait`, respectively.
pub fn struct_lockstep_tails(self,
source: Ty<'tcx>,

View file

@ -12,7 +12,7 @@ use session::config::Options;
use std::fs;
use std::io::{self, StdoutLock, Write};
use std::time::Instant;
use std::time::{Duration, Instant};
macro_rules! define_categories {
($($name:ident,)*) => {
@ -208,7 +208,20 @@ impl SelfProfiler {
}
fn stop_timer(&mut self) -> u64 {
let elapsed = self.current_timer.elapsed();
let elapsed = if cfg!(windows) {
// On Windows, timers don't always appear to be monotonic (see #51648)
// which can lead to panics when calculating elapsed time.
// Work around this by testing to see if the current time is less than
// our recorded time, and if it is, just returning 0.
let now = Instant::now();
if self.current_timer >= now {
Duration::new(0, 0)
} else {
self.current_timer.elapsed()
}
} else {
self.current_timer.elapsed()
};
self.current_timer = Instant::now();

View file

@ -700,6 +700,11 @@ fn link_natively(sess: &Session,
if sess.opts.target_triple.triple() == "wasm32-unknown-unknown" {
wasm::rewrite_imports(&out_filename, &codegen_results.crate_info.wasm_imports);
wasm::add_producer_section(
&out_filename,
&sess.edition().to_string(),
option_env!("CFG_VERSION").unwrap_or("unknown"),
);
}
}

View file

@ -17,6 +17,7 @@ use serialize::leb128;
// https://webassembly.github.io/spec/core/binary/modules.html#binary-importsec
const WASM_IMPORT_SECTION_ID: u8 = 2;
const WASM_CUSTOM_SECTION_ID: u8 = 0;
const WASM_EXTERNAL_KIND_FUNCTION: u8 = 0;
const WASM_EXTERNAL_KIND_TABLE: u8 = 1;
@ -121,6 +122,112 @@ pub fn rewrite_imports(path: &Path, import_map: &FxHashMap<String, String>) {
}
}
/// Add or augment the existing `producers` section to encode information about
/// the Rust compiler used to produce the wasm file.
pub fn add_producer_section(
path: &Path,
rust_version: &str,
rustc_version: &str,
) {
struct Field<'a> {
name: &'a str,
values: Vec<FieldValue<'a>>,
}
#[derive(Copy, Clone)]
struct FieldValue<'a> {
name: &'a str,
version: &'a str,
}
let wasm = fs::read(path).expect("failed to read wasm output");
let mut ret = WasmEncoder::new();
ret.data.extend(&wasm[..8]);
// skip the 8 byte wasm/version header
let rustc_value = FieldValue {
name: "rustc",
version: rustc_version,
};
let rust_value = FieldValue {
name: "Rust",
version: rust_version,
};
let mut fields = Vec::new();
let mut wrote_rustc = false;
let mut wrote_rust = false;
// Move all sections from the original wasm file to our output, skipping
// everything except the producers section
for (id, raw) in WasmSections(WasmDecoder::new(&wasm[8..])) {
if id != WASM_CUSTOM_SECTION_ID {
ret.byte(id);
ret.bytes(raw);
continue
}
let mut decoder = WasmDecoder::new(raw);
if decoder.str() != "producers" {
ret.byte(id);
ret.bytes(raw);
continue
}
// Read off the producers section into our fields outside the loop,
// we'll re-encode the producers section when we're done (to handle an
// entirely missing producers section as well).
info!("rewriting existing producers section");
for _ in 0..decoder.u32() {
let name = decoder.str();
let mut values = Vec::new();
for _ in 0..decoder.u32() {
let name = decoder.str();
let version = decoder.str();
values.push(FieldValue { name, version });
}
if name == "language" {
values.push(rust_value);
wrote_rust = true;
} else if name == "processed-by" {
values.push(rustc_value);
wrote_rustc = true;
}
fields.push(Field { name, values });
}
}
if !wrote_rust {
fields.push(Field {
name: "language",
values: vec![rust_value],
});
}
if !wrote_rustc {
fields.push(Field {
name: "processed-by",
values: vec![rustc_value],
});
}
// Append the producers section to the end of the wasm file.
let mut section = WasmEncoder::new();
section.str("producers");
section.u32(fields.len() as u32);
for field in fields {
section.str(field.name);
section.u32(field.values.len() as u32);
for value in field.values {
section.str(value.name);
section.str(value.version);
}
}
ret.byte(WASM_CUSTOM_SECTION_ID);
ret.bytes(&section.data);
fs::write(path, &ret.data).expect("failed to write wasm output");
}
struct WasmSections<'a>(WasmDecoder<'a>);
impl<'a> Iterator for WasmSections<'a> {

View file

@ -74,7 +74,7 @@ impl<'a, 'tcx: 'a> VirtualIndex {
/// The vtables are cached instead of created on every call.
///
/// The `trait_ref` encodes the erased self type. Hence if we are
/// making an object `Foo<Trait>` from a value of type `Foo<T>`, then
/// making an object `Foo<dyn Trait>` from a value of type `Foo<T>`, then
/// `trait_ref` would map `T:Trait`.
pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
cx: &Cx,

View file

@ -158,7 +158,9 @@ macro_rules! make_value_visitor {
) -> EvalResult<'tcx> {
self.walk_aggregate(v, fields)
}
/// Called each time we recurse down to a field, passing in old and new value.
/// Called each time we recurse down to a field of a "product-like" aggregate
/// (structs, tuples, arrays and the like, but not enums), passing in old and new value.
/// This gives the visitor the chance to track the stack of nested fields that
/// we are descending through.
#[inline(always)]
@ -171,6 +173,19 @@ macro_rules! make_value_visitor {
self.visit_value(new_val)
}
/// Called for recursing into the field of a generator. These are not known to be
/// initialized, so we treat them like unions.
#[inline(always)]
fn visit_generator_field(
&mut self,
_old_val: Self::V,
_field: usize,
new_val: Self::V,
) -> EvalResult<'tcx> {
self.visit_union(new_val)
}
/// Called when recursing into an enum variant.
#[inline(always)]
fn visit_variant(
&mut self,
@ -291,17 +306,33 @@ macro_rules! make_value_visitor {
// use that as an unambiguous signal for detecting primitives. Make sure
// we did not miss any primitive.
debug_assert!(fields > 0);
self.visit_union(v)?;
self.visit_union(v)
},
layout::FieldPlacement::Arbitrary { ref offsets, .. } => {
// FIXME: We collect in a vec because otherwise there are lifetime errors:
// Projecting to a field needs (mutable!) access to `ecx`.
let fields: Vec<EvalResult<'tcx, Self::V>> =
(0..offsets.len()).map(|i| {
v.project_field(self.ecx(), i as u64)
})
.collect();
self.visit_aggregate(v, fields.into_iter())?;
// Special handling needed for generators: All but the first field
// (which is the state) are actually implicitly `MaybeUninit`, i.e.,
// they may or may not be initialized, so we cannot visit them.
match v.layout().ty.sty {
ty::Generator(..) => {
let field = v.project_field(self.ecx(), 0)?;
self.visit_aggregate(v, std::iter::once(Ok(field)))?;
for i in 1..offsets.len() {
let field = v.project_field(self.ecx(), i as u64)?;
self.visit_generator_field(v, i, field)?;
}
Ok(())
}
_ => {
// FIXME: We collect in a vec because otherwise there are lifetime
// errors: Projecting to a field needs access to `ecx`.
let fields: Vec<EvalResult<'tcx, Self::V>> =
(0..offsets.len()).map(|i| {
v.project_field(self.ecx(), i as u64)
})
.collect();
self.visit_aggregate(v, fields.into_iter())
}
}
},
layout::FieldPlacement::Array { .. } => {
// Let's get an mplace first.
@ -317,10 +348,9 @@ macro_rules! make_value_visitor {
.map(|f| f.and_then(|f| {
Ok(Value::from_mem_place(f))
}));
self.visit_aggregate(v, iter)?;
self.visit_aggregate(v, iter)
}
}
Ok(())
}
}
}

View file

@ -178,10 +178,6 @@
//! Some things are not yet fully implemented in the current version of this
//! module.
//!
//! ### Initializers of Constants and Statics
//! Since no MIR is constructed yet for initializer expressions of constants and
//! statics we cannot inspect these properly.
//!
//! ### Const Fns
//! Ideally, no mono item should be generated for const fns unless there
//! is a call to them that cannot be evaluated at compile time. At the moment
@ -191,7 +187,6 @@
use rustc::hir::{self, CodegenFnAttrFlags};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::Node;
use rustc::hir::def_id::DefId;
use rustc::mir::interpret::{AllocId, ConstValue};
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
@ -741,27 +736,27 @@ fn should_monomorphize_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance:
ty::InstanceDef::CloneShim(..) => return true
};
return match tcx.hir.get_if_local(def_id) {
Some(Node::ForeignItem(..)) => {
false // foreign items are linked against, not codegened.
}
Some(_) => true,
None => {
if tcx.is_reachable_non_generic(def_id) ||
tcx.is_foreign_item(def_id) ||
is_available_upstream_generic(tcx, def_id, instance.substs)
{
// We can link to the item in question, no instance needed
// in this crate
false
} else {
if !tcx.is_mir_available(def_id) {
bug!("Cannot create local mono-item for {:?}", def_id)
}
true
}
}
};
if tcx.is_foreign_item(def_id) {
// We can always link to foreign items
return false;
}
if def_id.is_local() {
// local items cannot be referred to locally without monomorphizing them locally
return true;
}
if tcx.is_reachable_non_generic(def_id) ||
is_available_upstream_generic(tcx, def_id, instance.substs) {
// We can link to the item in question, no instance needed
// in this crate
return false;
}
if !tcx.is_mir_available(def_id) {
bug!("Cannot create local mono-item for {:?}", def_id)
}
return true;
fn is_available_upstream_generic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,

View file

@ -4710,7 +4710,18 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
ty::Visibility::Restricted(self.current_module.normal_ancestor_id)
}
ast::VisibilityKind::Restricted { ref path, id, .. } => {
// Visibilities are resolved as global by default, add starting root segment.
// For visibilities we are not ready to provide correct implementation of "uniform
// paths" right now, so on 2018 edition we only allow module-relative paths for now.
let first_ident = path.segments[0].ident;
if self.session.rust_2018() && !first_ident.is_path_segment_keyword() {
let msg = "relative paths are not supported in visibilities on 2018 edition";
self.session.struct_span_err(first_ident.span, msg)
.span_suggestion(path.span, "try", format!("crate::{}", path))
.emit();
return ty::Visibility::Public;
}
// On 2015 visibilities are resolved as crate-relative by default,
// add starting root segment if necessary.
let segments = path.make_root().iter().chain(path.segments.iter())
.map(|seg| Segment { ident: seg.ident, id: Some(seg.id) })
.collect::<Vec<_>>();
@ -4988,10 +4999,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
err.span_suggestion_with_applicability(
binding.span,
&rename_msg,
match (&directive.subclass, snippet.as_ref()) {
(ImportDirectiveSubclass::SingleImport { .. }, "self") =>
match directive.subclass {
ImportDirectiveSubclass::SingleImport { type_ns_only: true, .. } =>
format!("self as {}", suggested_name),
(ImportDirectiveSubclass::SingleImport { source, .. }, _) =>
ImportDirectiveSubclass::SingleImport { source, .. } =>
format!(
"{} as {}{}",
&snippet[..((source.span.hi().0 - binding.span.lo().0) as usize)],
@ -5002,13 +5013,13 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
""
}
),
(ImportDirectiveSubclass::ExternCrate { source, target, .. }, _) =>
ImportDirectiveSubclass::ExternCrate { source, target, .. } =>
format!(
"extern crate {} as {};",
source.unwrap_or(target.name),
suggested_name,
),
(_, _) => unreachable!(),
_ => unreachable!(),
},
Applicability::MaybeIncorrect,
);

View file

@ -864,7 +864,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
}
PathResult::NonModule(path_res) if path_res.base_def() == Def::Err => {
// The error was already reported earlier.
assert!(directive.imported_module.get().is_none());
assert!(!self.ambiguity_errors.is_empty() ||
directive.imported_module.get().is_none());
return None;
}
PathResult::Indeterminate | PathResult::NonModule(..) => unreachable!(),

View file

@ -36,8 +36,9 @@ use lint;
use std::iter;
use syntax::ast;
use syntax::ptr::P;
use syntax::feature_gate::{GateIssue, emit_feature_err};
use syntax::ptr::P;
use syntax::util::lev_distance::find_best_match_for_name;
use syntax_pos::{DUMMY_SP, Span, MultiSpan};
pub trait AstConv<'gcx, 'tcx> {
@ -1303,6 +1304,32 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
Err(ErrorReported) => return (tcx.types.err, Def::Err),
}
}
(&ty::Adt(adt_def, _substs), Def::Enum(_did)) => {
let ty_str = ty.to_string();
// Incorrect enum variant
let mut err = tcx.sess.struct_span_err(
span,
&format!("no variant `{}` on enum `{}`", &assoc_name.as_str(), ty_str),
);
// Check if it was a typo
let input = adt_def.variants.iter().map(|variant| &variant.name);
if let Some(suggested_name) = find_best_match_for_name(
input,
&assoc_name.as_str(),
None,
) {
err.span_suggestion_with_applicability(
span,
"did you mean",
format!("{}::{}", ty_str, suggested_name.to_string()),
Applicability::MaybeIncorrect,
);
} else {
err.span_label(span, "unknown variant");
}
err.emit();
return (tcx.types.err, Def::Err);
}
_ => {
// Don't print TyErr to the user.
if !ty.references_error() {

View file

@ -208,6 +208,10 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
fulfillment_cx: RefCell<Box<dyn TraitEngine<'tcx>>>,
// Some additional `Sized` obligations badly affect type inference.
// These obligations are added in a later stage of typeck.
deferred_sized_obligations: RefCell<Vec<(Ty<'tcx>, Span, traits::ObligationCauseCode<'tcx>)>>,
// When we process a call like `c()` where `c` is a closure type,
// we may not have decided yet whether `c` is a `Fn`, `FnMut`, or
// `FnOnce` closure. In that case, we defer full resolution of the
@ -644,6 +648,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
infcx,
fulfillment_cx: RefCell::new(TraitEngine::new(tcx)),
locals: RefCell::new(Default::default()),
deferred_sized_obligations: RefCell::new(Vec::new()),
deferred_call_resolutions: RefCell::new(Default::default()),
deferred_cast_checks: RefCell::new(Vec::new()),
deferred_generator_interiors: RefCell::new(Vec::new()),
@ -907,6 +912,10 @@ fn typeck_tables_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fcx.closure_analyze(body);
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
fcx.resolve_generator_interiors(def_id);
for (ty, span, code) in fcx.deferred_sized_obligations.borrow_mut().drain(..) {
fcx.require_type_is_sized(ty, span, code);
}
fcx.select_all_obligations_or_error();
if fn_decl.is_some() {
@ -2345,6 +2354,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
self.require_type_meets(ty, span, code, lang_item);
}
pub fn require_type_is_sized_deferred(&self,
ty: Ty<'tcx>,
span: Span,
code: traits::ObligationCauseCode<'tcx>)
{
self.deferred_sized_obligations.borrow_mut().push((ty, span, code));
}
pub fn register_bound(&self,
ty: Ty<'tcx>,
def_id: DefId,
@ -3939,6 +3956,31 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
tcx.types.err
};
if let ty::FnDef(..) = ty.sty {
let fn_sig = ty.fn_sig(tcx);
if !tcx.features().unsized_locals {
// We want to remove some Sized bounds from std functions,
// but don't want to expose the removal to stable Rust.
// i.e. we don't want to allow
//
// ```rust
// drop as fn(str);
// ```
//
// to work in stable even if the Sized bound on `drop` is relaxed.
for i in 0..fn_sig.inputs().skip_binder().len() {
let input = tcx.erase_late_bound_regions(&fn_sig.input(i));
self.require_type_is_sized_deferred(input, expr.span,
traits::SizedArgumentType);
}
}
// Here we want to prevent struct constructors from returning unsized types.
// There were two cases this happened: fn pointer coercion in stable
// and usual function call in presense of unsized_locals.
let output = tcx.erase_late_bound_regions(&fn_sig.output());
self.require_type_is_sized_deferred(output, expr.span, traits::SizedReturnType);
}
// We always require that the type provided as the value for
// a type parameter outlives the moment of instantiation.
let substs = self.tables.borrow().node_substs(expr.hir_id);

View file

@ -256,7 +256,7 @@ fn initial_buffer_size(file: &File) -> usize {
/// use std::fs;
/// use std::net::SocketAddr;
///
/// fn main() -> Result<(), Box<std::error::Error + 'static>> {
/// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
/// let foo: SocketAddr = String::from_utf8_lossy(&fs::read("address.txt")?).parse()?;
/// Ok(())
/// }
@ -298,7 +298,7 @@ pub fn read<P: AsRef<Path>>(path: P) -> io::Result<Vec<u8>> {
/// use std::fs;
/// use std::net::SocketAddr;
///
/// fn main() -> Result<(), Box<std::error::Error + 'static>> {
/// fn main() -> Result<(), Box<dyn std::error::Error + 'static>> {
/// let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?;
/// Ok(())
/// }

View file

@ -1889,42 +1889,6 @@ mod tests {
cmd
}
#[test]
fn test_inherit_env() {
use env;
let result = env_cmd().output().unwrap();
let output = String::from_utf8(result.stdout).unwrap();
for (ref k, ref v) in env::vars() {
// Don't check android RANDOM variable which seems to change
// whenever the shell runs, and our `env_cmd` is indeed running a
// shell which means it'll get a different RANDOM than we probably
// have.
//
// Also skip env vars with `-` in the name on android because, well,
// I'm not sure. It appears though that the `set` command above does
// not print env vars with `-` in the name, so we just skip them
// here as we won't find them in the output. Note that most env vars
// use `_` instead of `-`, but our build system sets a few env vars
// with `-` in the name.
if cfg!(target_os = "android") &&
(*k == "RANDOM" || k.contains("-")) {
continue
}
// Windows has hidden environment variables whose names start with
// equals signs (`=`). Those do not show up in the output of the
// `set` command.
assert!((cfg!(windows) && k.starts_with("=")) ||
k.starts_with("DYLD") ||
output.contains(&format!("{}={}", *k, *v)) ||
output.contains(&format!("{}='{}'", *k, *v)),
"output doesn't contain `{}={}`\n{}",
k, v, output);
}
}
#[test]
fn test_override_env() {
use env;

View file

@ -19,7 +19,7 @@ use ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal};
use ext::tt::macro_parser::{parse, parse_failure_msg};
use ext::tt::quoted;
use ext::tt::transcribe::transcribe;
use feature_gate::{self, emit_feature_err, Features, GateIssue};
use feature_gate::Features;
use parse::{Directory, ParseSess};
use parse::parser::Parser;
use parse::token::{self, NtTT};
@ -1027,26 +1027,21 @@ fn has_legal_fragment_specifier(sess: &ParseSess,
Ok(())
}
fn is_legal_fragment_specifier(sess: &ParseSess,
features: &Features,
attrs: &[ast::Attribute],
fn is_legal_fragment_specifier(_sess: &ParseSess,
_features: &Features,
_attrs: &[ast::Attribute],
frag_name: &str,
frag_span: Span) -> bool {
_frag_span: Span) -> bool {
/*
* If new fragment specifiers are invented in nightly, `_sess`,
* `_features`, `_attrs`, and `_frag_span` will be useful here
* for checking against feature gates. See past versions of
* this function.
*/
match frag_name {
"item" | "block" | "stmt" | "expr" | "pat" | "lifetime" |
"path" | "ty" | "ident" | "meta" | "tt" | "vis" | "" => true,
"literal" => {
if !features.macro_literal_matcher &&
!attr::contains_name(attrs, "allow_internal_unstable") {
let explain = feature_gate::EXPLAIN_LITERAL_MATCHER;
emit_feature_err(sess,
"macro_literal_matcher",
frag_span,
GateIssue::Language,
explain);
}
true
},
"path" | "ty" | "ident" | "meta" | "tt" | "vis" | "literal" |
"" => true,
_ => false,
}
}

View file

@ -436,9 +436,6 @@ declare_features! (
// Allows irrefutable patterns in if-let and while-let statements (RFC 2086)
(active, irrefutable_let_patterns, "1.27.0", Some(44495), None),
// Allows use of the :literal macro fragment specifier (RFC 1576)
(active, macro_literal_matcher, "1.27.0", Some(35625), None),
// inconsistent bounds in where clauses
(active, trivial_bounds, "1.28.0", Some(48214), None),
@ -690,6 +687,8 @@ declare_features! (
(accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
// `extern crate foo as bar;` puts `bar` into extern prelude.
(accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None),
// Allows use of the :literal macro fragment specifier (RFC 1576)
(accepted, macro_literal_matcher, "1.31.0", Some(35625), None),
);
// If you change this, please modify src/doc/unstable-book as well. You must
@ -1425,9 +1424,6 @@ pub const EXPLAIN_DEPR_CUSTOM_DERIVE: &'static str =
pub const EXPLAIN_DERIVE_UNDERSCORE: &'static str =
"attributes of the form `#[derive_*]` are reserved for the compiler";
pub const EXPLAIN_LITERAL_MATCHER: &'static str =
":literal fragment specifier is experimental and subject to change";
pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &'static str =
"unsized tuple coercion is not stable enough for use and is subject to change";

View file

@ -11,11 +11,10 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=lazy
// NB: We do not expect *any* monomorphization to be generated here.
#![deny(dead_code)]
#![crate_type = "rlib"]
//~ MONO_ITEM fn unreferenced_const_fn::foo[0] @@ unreferenced_const_fn-cgu.0[External]
pub const fn foo(x: u32) -> u32 {
x + 0xf00
}

View file

@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// ignore-tidy-linelength
// ignore-windows failing on win32 bot
// ignore-freebsd: gdb package too new
// ignore-android: FIXME(#10381)
@ -20,10 +21,10 @@
// gdb-command: run
// gdb-command: print btree_set
// gdb-check:$1 = BTreeSet<i32>(len: 3) = {3, 5, 7}
// gdb-check:$1 = BTreeSet<i32>(len: 15) = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
// gdb-command: print btree_map
// gdb-check:$2 = BTreeMap<i32, i32>(len: 3) = {[3] = 3, [5] = 7, [7] = 4}
// gdb-check:$2 = BTreeMap<i32, i32>(len: 15) = {[0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4, [5] = 5, [6] = 6, [7] = 7, [8] = 8, [9] = 9, [10] = 10, [11] = 11, [12] = 12, [13] = 13, [14] = 14}
// gdb-command: print vec_deque
// gdb-check:$3 = VecDeque<i32>(len: 3, cap: 8) = {5, 3, 7}
@ -41,15 +42,15 @@ fn main() {
// BTreeSet
let mut btree_set = BTreeSet::new();
btree_set.insert(5);
btree_set.insert(3);
btree_set.insert(7);
for i in 0..15 {
btree_set.insert(i);
}
// BTreeMap
let mut btree_map = BTreeMap::new();
btree_map.insert(5, 7);
btree_map.insert(3, 3);
btree_map.insert(7, 4);
for i in 0..15 {
btree_map.insert(i, i);
}
// VecDeque
let mut vec_deque = VecDeque::new();

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(const_int_conversion, const_int_ops, reverse_bits, int_to_from_bytes)]
#![feature(const_int_conversion, const_int_ops, reverse_bits)]
const REVERSE: u32 = 0x12345678_u32.reverse_bits();
const FROM_BE_BYTES: i32 = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]);

View file

@ -0,0 +1,25 @@
// ignore-emscripten
// ignore-wasm32
use std::env;
use std::process::Command;
fn main() {
if env::args().nth(1).map(|s| s == "print").unwrap_or(false) {
for (k, v) in env::vars() {
println!("{}={}", k, v);
}
return
}
let me = env::current_exe().unwrap();
let result = Command::new(me).arg("print").output().unwrap();
let output = String::from_utf8(result.stdout).unwrap();
for (k, v) in env::vars() {
assert!(output.contains(&format!("{}={}", k, v)),
"output doesn't contain `{}={}`\n{}",
k, v, output);
}
}

View file

@ -9,7 +9,6 @@
// except according to those terms.
// run-pass
#![feature(macro_literal_matcher)]
macro_rules! a {
($i:literal) => { "right" };

View file

@ -9,7 +9,6 @@
// except according to those terms.
// run-pass
#![feature(macro_literal_matcher)]
macro_rules! mtester {
($l:literal) => {

View file

@ -8,7 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Ensure that both `Box<Error + Send + Sync>` and `Box<Error>` can be obtained from `String`.
// Ensure that both `Box<dyn Error + Send + Sync>` and `Box<dyn Error>` can be
// obtained from `String`.
use std::error::Error;

View file

@ -34,4 +34,5 @@ fn main() {
udrop::<[u8]>((*foo()));
udrop::<[u8]>((*tfoo()).1);
*afoo() + 42;
udrop as fn([u8]);
}

View file

@ -10,6 +10,24 @@
// Crate that exports a const fn. Used for testing cross-crate.
#![feature(const_fn)]
#![crate_type="rlib"]
pub const fn foo() -> usize { 22 } //~ ERROR const fn is unstable
pub const fn foo() -> usize { 22 }
pub const fn bar() -> fn() {
fn x() {}
x
}
#[inline]
pub const fn bar_inlined() -> fn() {
fn x() {}
x
}
#[inline(always)]
pub const fn bar_inlined_always() -> fn() {
fn x() {}
x
}

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(reverse_bits, int_to_from_bytes)]
#![feature(reverse_bits)]
fn main() {
let x: &'static i32 = &(5_i32.reverse_bits());

View file

@ -0,0 +1,10 @@
// compile-pass
// aux-build:const_fn_lib.rs
extern crate const_fn_lib;
fn main() {
const_fn_lib::bar()();
const_fn_lib::bar_inlined()();
const_fn_lib::bar_inlined_always()();
}

View file

@ -1,19 +0,0 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Test that the :lifetime macro fragment cannot be used when macro_lifetime_matcher
// feature gate is not used.
macro_rules! m { ($lt:literal) => {} }
//~^ ERROR :literal fragment specifier is experimental and subject to change
fn main() {
m!("some string literal");
}

View file

@ -1,11 +0,0 @@
error[E0658]: :literal fragment specifier is experimental and subject to change (see issue #35625)
--> $DIR/feature-gate-macro-literal-matcher.rs:14:19
|
LL | macro_rules! m { ($lt:literal) => {} }
| ^^^^^^^^^^^
|
= help: add #![feature(macro_literal_matcher)] to the crate attributes to enable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0658`.

View file

@ -1,3 +1,5 @@
pub mod issue_56125 {}
pub mod last_segment {
pub mod issue_56125 {}
}

View file

@ -2,11 +2,24 @@
// compile-flags:--extern issue_56125
// aux-build:issue-56125.rs
use issue_56125::last_segment::*;
//~^ ERROR `issue_56125` is ambiguous
//~| ERROR unresolved import `issue_56125::last_segment`
use issue_56125::non_last_segment::non_last_segment::*;
//~^ ERROR `issue_56125` is ambiguous
//~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125`
#![feature(uniform_paths)]
mod m1 {
use issue_56125::last_segment::*;
//~^ ERROR `issue_56125` is ambiguous
//~| ERROR unresolved import `issue_56125::last_segment`
}
mod m2 {
use issue_56125::non_last_segment::non_last_segment::*;
//~^ ERROR `issue_56125` is ambiguous
//~| ERROR failed to resolve: could not find `non_last_segment` in `issue_56125`
}
mod m3 {
mod empty {}
use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
}
fn main() {}

View file

@ -1,46 +1,67 @@
error[E0433]: failed to resolve: could not find `non_last_segment` in `issue_56125`
--> $DIR/issue-56125.rs:8:18
--> $DIR/issue-56125.rs:14:22
|
LL | use issue_56125::non_last_segment::non_last_segment::*;
| ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125`
LL | use issue_56125::non_last_segment::non_last_segment::*;
| ^^^^^^^^^^^^^^^^ could not find `non_last_segment` in `issue_56125`
error[E0432]: unresolved import `issue_56125::last_segment`
--> $DIR/issue-56125.rs:5:18
--> $DIR/issue-56125.rs:8:22
|
LL | use issue_56125::last_segment::*;
| ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125`
LL | use issue_56125::last_segment::*;
| ^^^^^^^^^^^^ could not find `last_segment` in `issue_56125`
error[E0432]: unresolved import `empty::issue_56125`
--> $DIR/issue-56125.rs:21:9
|
LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
| ^^^^^^^^^^^^^^^^^^ no `issue_56125` in `m3::empty`
error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
--> $DIR/issue-56125.rs:5:5
--> $DIR/issue-56125.rs:8:9
|
LL | use issue_56125::last_segment::*;
| ^^^^^^^^^^^ ambiguous name
LL | use issue_56125::last_segment::*;
| ^^^^^^^^^^^ ambiguous name
|
= note: `issue_56125` could refer to an extern crate passed with `--extern`
= help: use `::issue_56125` to refer to this extern crate unambiguously
note: `issue_56125` could also refer to the module imported here
--> $DIR/issue-56125.rs:5:5
--> $DIR/issue-56125.rs:8:9
|
LL | use issue_56125::last_segment::*;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | use issue_56125::last_segment::*;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use `self::issue_56125` to refer to this module unambiguously
error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
--> $DIR/issue-56125.rs:8:5
--> $DIR/issue-56125.rs:14:9
|
LL | use issue_56125::non_last_segment::non_last_segment::*;
| ^^^^^^^^^^^ ambiguous name
LL | use issue_56125::non_last_segment::non_last_segment::*;
| ^^^^^^^^^^^ ambiguous name
|
= note: `issue_56125` could refer to an extern crate passed with `--extern`
= help: use `::issue_56125` to refer to this extern crate unambiguously
note: `issue_56125` could also refer to the module imported here
--> $DIR/issue-56125.rs:5:5
--> $DIR/issue-56125.rs:14:9
|
LL | use issue_56125::last_segment::*;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | use issue_56125::non_last_segment::non_last_segment::*;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= help: use `self::issue_56125` to refer to this module unambiguously
error: aborting due to 4 previous errors
error[E0659]: `issue_56125` is ambiguous (name vs any other name during import resolution)
--> $DIR/issue-56125.rs:22:9
|
LL | use issue_56125::*; //~ ERROR `issue_56125` is ambiguous
| ^^^^^^^^^^^ ambiguous name
|
= note: `issue_56125` could refer to an extern crate passed with `--extern`
= help: use `::issue_56125` to refer to this extern crate unambiguously
note: `issue_56125` could also refer to the unresolved item imported here
--> $DIR/issue-56125.rs:21:9
|
LL | use empty::issue_56125; //~ ERROR unresolved import `empty::issue_56125`
| ^^^^^^^^^^^^^^^^^^
= help: use `self::issue_56125` to refer to this unresolved item unambiguously
error: aborting due to 6 previous errors
Some errors occurred: E0432, E0433, E0659.
For more information about an error, try `rustc --explain E0432`.

View file

@ -1,22 +0,0 @@
error[E0161]: cannot move a value of type X: the size of X cannot be statically determined
--> $DIR/issue-30355.rs:15:6
|
LL | &X(*Y)
| ^^^^^
error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined
--> $DIR/issue-30355.rs:15:8
|
LL | &X(*Y)
| ^^
error[E0508]: cannot move out of type `[u8]`, a non-copy slice
--> $DIR/issue-30355.rs:15:8
|
LL | &X(*Y)
| ^^ cannot move out of here
error: aborting due to 3 previous errors
Some errors occurred: E0161, E0508.
For more information about an error, try `rustc --explain E0161`.

View file

@ -13,9 +13,7 @@ pub struct X([u8]);
pub static Y: &'static X = {
const Y: &'static [u8] = b"";
&X(*Y)
//~^ ERROR cannot move out
//~^^ ERROR cannot move a
//~^^^ ERROR cannot move a
//~^ ERROR E0277
};
fn main() {}

View file

@ -1,22 +1,14 @@
error[E0161]: cannot move a value of type X: the size of X cannot be statically determined
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/issue-30355.rs:15:6
|
LL | &X(*Y)
| ^^^^^
error[E0161]: cannot move a value of type [u8]: the size of [u8] cannot be statically determined
--> $DIR/issue-30355.rs:15:8
| ^ doesn't have a size known at compile-time
|
LL | &X(*Y)
| ^^
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: all function arguments must have a statically known size
= help: unsized locals are gated as an unstable feature
error[E0507]: cannot move out of borrowed content
--> $DIR/issue-30355.rs:15:8
|
LL | &X(*Y)
| ^^ cannot move out of borrowed content
error: aborting due to previous error
error: aborting due to 3 previous errors
Some errors occurred: E0161, E0507.
For more information about an error, try `rustc --explain E0161`.
For more information about this error, try `rustc --explain E0277`.

View file

@ -14,8 +14,8 @@ enum S {
fn bug(l: S) {
match l {
S::B{ } => { },
//~^ ERROR ambiguous associated type
S::B { } => { },
//~^ ERROR no variant `B` on enum `S`
}
}

View file

@ -1,9 +1,8 @@
error[E0223]: ambiguous associated type
error: no variant `B` on enum `S`
--> $DIR/issue-34209.rs:17:9
|
LL | S::B{ } => { },
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::B`
LL | S::B { } => { },
| ^^^^ help: did you mean: `S::A`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0223`.

View file

@ -19,4 +19,7 @@ use foo as self;
use foo::self;
use foo::A;
use foo::{self as A};
fn main() {}

View file

@ -25,7 +25,21 @@ help: you can use `as` to change the binding name of the import
LL | use foo::{self as other_foo};
| ^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
error[E0252]: the name `A` is defined multiple times
--> $DIR/import-self.rs:23:11
|
LL | use foo::A;
| ------ previous import of the type `A` here
LL | use foo::{self as A};
| ^^^^^^^^^ `A` reimported here
|
= note: `A` must be defined only once in the type namespace of this module
help: you can use `as` to change the binding name of the import
|
LL | use foo::{self as OtherA};
| ^^^^^^^^^^^^^^
Some errors occurred: E0255, E0429.
For more information about an error, try `rustc --explain E0255`.
error: aborting due to 4 previous errors
Some errors occurred: E0252, E0255, E0429.
For more information about an error, try `rustc --explain E0252`.

View file

@ -0,0 +1,13 @@
// edition:2018
mod m {
pub(in crate) struct S1; // OK
pub(in super) struct S2; // OK
pub(in self) struct S3; // OK
pub(in ::core) struct S4;
//~^ ERROR visibilities can only be restricted to ancestor modules
pub(in a::b) struct S5;
//~^ ERROR relative paths are not supported in visibilities on 2018 edition
}
fn main() {}

View file

@ -0,0 +1,16 @@
error: visibilities can only be restricted to ancestor modules
--> $DIR/relative-2018.rs:7:12
|
LL | pub(in ::core) struct S4;
| ^^^^^^
error: relative paths are not supported in visibilities on 2018 edition
--> $DIR/relative-2018.rs:9:12
|
LL | pub(in a::b) struct S5;
| ^---
| |
| help: try: `crate::a::b`
error: aborting due to 2 previous errors

View file

@ -0,0 +1,15 @@
#[derive(Debug)]
enum Shape {
Square { size: i32 },
Circle { radius: i32 },
}
struct S {
x: usize,
}
fn main() {
println!("My shape is {:?}", Shape::Squareee { size: 5});
println!("My shape is {:?}", Shape::Circl { size: 5});
println!("My shape is {:?}", Shape::Rombus{ size: 5});
}

View file

@ -0,0 +1,20 @@
error: no variant `Squareee` on enum `Shape`
--> $DIR/suggest-variants.rs:12:34
|
LL | println!("My shape is {:?}", Shape::Squareee { size: 5});
| ^^^^^^^^^^^^^^^ help: did you mean: `Shape::Square`
error: no variant `Circl` on enum `Shape`
--> $DIR/suggest-variants.rs:13:34
|
LL | println!("My shape is {:?}", Shape::Circl { size: 5});
| ^^^^^^^^^^^^ help: did you mean: `Shape::Circle`
error: no variant `Rombus` on enum `Shape`
--> $DIR/suggest-variants.rs:14:34
|
LL | println!("My shape is {:?}", Shape::Rombus{ size: 5});
| ^^^^^^^^^^^^^ unknown variant
error: aborting due to 3 previous errors

View file

@ -0,0 +1,3 @@
#![feature(unsized_locals)]
pub fn udrop<T: ?Sized>(_x: T) {}

View file

@ -0,0 +1,7 @@
#![feature(unsized_locals)]
fn main() {
struct A<X: ?Sized>(X);
A as fn(str) -> A<str>;
//~^ERROR the size for values of type `str` cannot be known at compilation time
}

View file

@ -0,0 +1,14 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/issue-50940-with-feature.rs:5:5
|
LL | A as fn(str) -> A<str>;
| ^ doesn't have a size known at compile-time
|
= help: within `main::A<str>`, the trait `std::marker::Sized` is not implemented for `str`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because it appears within the type `main::A<str>`
= note: the return type of a function must have a statically known size
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -0,0 +1,5 @@
fn main() {
struct A<X: ?Sized>(X);
A as fn(str) -> A<str>;
//~^ERROR the size for values of type `str` cannot be known at compilation time
}

View file

@ -0,0 +1,14 @@
error[E0277]: the size for values of type `str` cannot be known at compilation time
--> $DIR/issue-50940.rs:3:5
|
LL | A as fn(str) -> A<str>;
| ^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `str`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: all function arguments must have a statically known size
= help: unsized locals are gated as an unstable feature
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -23,4 +23,6 @@ fn main() {
//~^ERROR E0277
udrop::<A<[u8]>>(A { 0: *foo() });
//~^ERROR E0277
udrop::<A<[u8]>>(A(*foo()));
//~^ERROR E0277
}

View file

@ -20,6 +20,17 @@ LL | udrop::<A<[u8]>>(A { 0: *foo() });
= note: required because it appears within the type `A<[u8]>`
= note: structs must have a statically known size to be initialized
error: aborting due to 2 previous errors
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/unsized-exprs.rs:26:22
|
LL | udrop::<A<[u8]>>(A(*foo()));
| ^ doesn't have a size known at compile-time
|
= help: within `A<[u8]>`, the trait `std::marker::Sized` is not implemented for `[u8]`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because it appears within the type `A<[u8]>`
= note: the return type of a function must have a statically known size
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -21,6 +21,4 @@ impl std::ops::Add<i32> for A<[u8]> {
fn main() {
udrop::<[u8]>(foo()[..]);
//~^ERROR cannot move out of indexed content
// FIXME: should be error
udrop::<A<[u8]>>(A(*foo()));
}

View file

@ -0,0 +1,10 @@
// aux-build:ufuncs.rs
extern crate ufuncs;
use ufuncs::udrop;
fn main() {
udrop as fn([u8]);
//~^ERROR E0277
}

View file

@ -0,0 +1,14 @@
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
--> $DIR/unsized-exprs3.rs:8:5
|
LL | udrop as fn([u8]);
| ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `[u8]`
= note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: all function arguments must have a statically known size
= help: unsized locals are gated as an unstable feature
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.