diff --git a/src/doc/unstable-book/src/language-features/macro-literal-matcher.md b/src/doc/unstable-book/src/language-features/macro-literal-matcher.md deleted file mode 100644 index 870158200dee9..0000000000000 --- a/src/doc/unstable-book/src/language-features/macro-literal-matcher.md +++ /dev/null @@ -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 - ------------------------- diff --git a/src/doc/unstable-book/src/language-features/unsized-locals.md b/src/doc/unstable-book/src/language-features/unsized-locals.md index 6f7cf754ae083..1165ab93a1469 100644 --- a/src/doc/unstable-book/src/language-features/unsized-locals.md +++ b/src/doc/unstable-book/src/language-features/unsized-locals.md @@ -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. diff --git a/src/etc/debugger_pretty_printers_common.py b/src/etc/debugger_pretty_printers_common.py index 1797f6708ac5b..b99e401929e62 100644 --- a/src/etc/debugger_pretty_printers_common.py +++ b/src/etc/debugger_pretty_printers_common.py @@ -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) diff --git a/src/etc/gdb_rust_pretty_printing.py b/src/etc/gdb_rust_pretty_printing.py index 4c74653654723..a376c8593f4c0 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -319,6 +319,32 @@ def children(self): 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 @@ def display_hint(): 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 @@ def display_hint(): 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): diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 63b262d1f3d98..c3a84bf778d03 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -489,7 +489,7 @@ impl Box { /// ``` /// use std::any::Any; /// - /// fn print_if_string(value: Box) { + /// fn print_if_string(value: Box) { /// if let Ok(string) = value.downcast::() { /// println!("String ({}): {}", string.len(), string); /// } @@ -523,7 +523,7 @@ impl Box { /// ``` /// use std::any::Any; /// - /// fn print_if_string(value: Box) { + /// fn print_if_string(value: Box) { /// if let Ok(string) = value.downcast::() { /// println!("String ({}): {}", string.len(), string); /// } @@ -618,10 +618,10 @@ impl FusedIterator for Box {} /// `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` in a data structure, you should use -/// `Box`. The two traits behave essentially the same, except +/// `Box` in a data structure, you should use +/// `Box`. 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` +/// that `FnBox` may be deprecated in the future if `Box` /// closures become directly usable.) /// /// # Examples @@ -629,7 +629,7 @@ impl FusedIterator for Box {} /// 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 i32>` and not `Box i32>` and not `Box i32>`. /// /// ``` @@ -638,8 +638,8 @@ impl FusedIterator for Box {} /// use std::boxed::FnBox; /// use std::collections::HashMap; /// -/// fn make_map() -> HashMap i32>> { -/// let mut map: HashMap i32>> = HashMap::new(); +/// fn make_map() -> HashMap i32>> { +/// let mut map: HashMap i32>> = HashMap::new(); /// map.insert(1, Box::new(|| 22)); /// map.insert(2, Box::new(|| 44)); /// map diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs index 705345ce963bb..3ca6de191de2d 100644 --- a/src/liballoc/rc.rs +++ b/src/liballoc/rc.rs @@ -633,7 +633,7 @@ impl Rc { impl Rc { #[inline] #[stable(feature = "rc_downcast", since = "1.29.0")] - /// Attempt to downcast the `Rc` to a concrete type. + /// Attempt to downcast the `Rc` to a concrete type. /// /// # Examples /// @@ -641,7 +641,7 @@ impl Rc { /// use std::any::Any; /// use std::rc::Rc; /// - /// fn print_if_string(value: Rc) { + /// fn print_if_string(value: Rc) { /// if let Ok(string) = value.downcast::() { /// println!("String ({}): {}", string.len(), string); /// } diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index 30b7b45468412..9deae12482976 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -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::()] { @@ -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::()] { @@ -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::()] { @@ -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 { @@ -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 { @@ -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 { @@ -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::()] { @@ -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::()] { @@ -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::()] { @@ -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 { @@ -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 { @@ -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 { diff --git a/src/libcore/raw.rs b/src/libcore/raw.rs index 495b9afe86023..3d4bccb4f9d65 100644 --- a/src/libcore/raw.rs +++ b/src/libcore/raw.rs @@ -21,7 +21,7 @@ /// The representation of a trait object like `&SomeTrait`. /// /// This struct has the same layout as types like `&SomeTrait` and -/// `Box`. +/// `Box`. /// /// `TraitObject` is guaranteed to match layouts, but it is not the /// type of trait objects (e.g. the fields are not directly accessible diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs index c612d6ad1bb24..ab63e882c4a55 100644 --- a/src/librustc/mir/interpret/allocation.rs +++ b/src/librustc/mir/interpret/allocation.rs @@ -172,10 +172,11 @@ impl<'tcx, Tag: Copy, Extra: AllocationExtra> Allocation { 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> Allocation { }, }; - { - 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 { diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index a9ea1c9a10931..af1255c438a95 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -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` to a `Box` + /// `&[i32;N]` to a `&[i32]`, or a `Box` to a `Box` /// (presuming `T: Trait`). Unsize, } diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index d688d93b80842..1187c53305d1c 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -826,8 +826,10 @@ impl Session { } pub fn profiler ()>(&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) { diff --git a/src/librustc/ty/adjustment.rs b/src/librustc/ty/adjustment.rs index 3263da8fda365..83521c5f72406 100644 --- a/src/librustc/ty/adjustment.rs +++ b/src/librustc/ty/adjustment.rs @@ -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` to `Box` is an interesting special case. In +/// 3. Coercing a `Box` to `Box` 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 diff --git a/src/librustc/ty/instance.rs b/src/librustc/ty/instance.rs index b6691df39c120..411a6e7e6238e 100644 --- a/src/librustc/ty/instance.rs +++ b/src/librustc/ty/instance.rs @@ -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() } } diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index f0885f960516d..51b197d7b990b 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -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)`, the result will be `(Foo, Trait)`, + /// For `(Foo>, Foo)`, the result will be `(Foo, Trait)`, /// whereas struct_tail produces `T`, and `Trait`, respectively. pub fn struct_lockstep_tails(self, source: Ty<'tcx>, diff --git a/src/librustc/util/profiling.rs b/src/librustc/util/profiling.rs index dfd3f2ee184ce..6540a09d87763 100644 --- a/src/librustc/util/profiling.rs +++ b/src/librustc/util/profiling.rs @@ -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(); diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs index 8380b71362138..89d84acdd8876 100644 --- a/src/librustc_codegen_llvm/back/link.rs +++ b/src/librustc_codegen_llvm/back/link.rs @@ -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"), + ); } } diff --git a/src/librustc_codegen_llvm/back/wasm.rs b/src/librustc_codegen_llvm/back/wasm.rs index 7101255173caf..1a5c65f3c4397 100644 --- a/src/librustc_codegen_llvm/back/wasm.rs +++ b/src/librustc_codegen_llvm/back/wasm.rs @@ -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) { } } +/// 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>, + } + + #[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(§ion.data); + + fs::write(path, &ret.data).expect("failed to write wasm output"); +} + struct WasmSections<'a>(WasmDecoder<'a>); impl<'a> Iterator for WasmSections<'a> { diff --git a/src/librustc_codegen_ssa/meth.rs b/src/librustc_codegen_ssa/meth.rs index e45cccee34946..d70fcf60fdf35 100644 --- a/src/librustc_codegen_ssa/meth.rs +++ b/src/librustc_codegen_ssa/meth.rs @@ -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` from a value of type `Foo`, then +/// making an object `Foo` from a value of type `Foo`, then /// `trait_ref` would map `T:Trait`. pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>( cx: &Cx, diff --git a/src/librustc_mir/interpret/visitor.rs b/src/librustc_mir/interpret/visitor.rs index f0a71242599bf..81e56f3115d26 100644 --- a/src/librustc_mir/interpret/visitor.rs +++ b/src/librustc_mir/interpret/visitor.rs @@ -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> = - (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> = + (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(()) } } } diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index b4ffb39a2ebd6..7531f62fdab7b 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -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, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 12dabd2a31da1..443b1ccdef836 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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::>(); @@ -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, ); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 616cc9d2fc51b..52e3e54b9f931 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -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!(), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a8164c85e821d..4fbbe58445254 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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() { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e36c0ae2a1902..e30a79b25de7f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -208,6 +208,10 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { fulfillment_cx: RefCell>>, + // Some additional `Sized` obligations badly affect type inference. + // These obligations are added in a later stage of typeck. + deferred_sized_obligations: RefCell, 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); diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index f4703dec187b8..92678dd5cede0 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -256,7 +256,7 @@ fn initial_buffer_size(file: &File) -> usize { /// use std::fs; /// use std::net::SocketAddr; /// -/// fn main() -> Result<(), Box> { +/// fn main() -> Result<(), Box> { /// let foo: SocketAddr = String::from_utf8_lossy(&fs::read("address.txt")?).parse()?; /// Ok(()) /// } @@ -298,7 +298,7 @@ pub fn read>(path: P) -> io::Result> { /// use std::fs; /// use std::net::SocketAddr; /// -/// fn main() -> Result<(), Box> { +/// fn main() -> Result<(), Box> { /// let foo: SocketAddr = fs::read_to_string("address.txt")?.parse()?; /// Ok(()) /// } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 51481e129df8d..2d0848252be6d 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -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; diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 6bba891278aca..d526e464ba4f5 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -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, } } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 2f5db9bd08155..73567765a04c4 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -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"; diff --git a/src/test/codegen-units/item-collection/unreferenced-const-fn.rs b/src/test/codegen-units/item-collection/unreferenced-const-fn.rs index c4a49fd4ec4d6..5e181870fed65 100644 --- a/src/test/codegen-units/item-collection/unreferenced-const-fn.rs +++ b/src/test/codegen-units/item-collection/unreferenced-const-fn.rs @@ -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 } diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs index 0d3f4b90f23ed..a51be370aa44b 100644 --- a/src/test/debuginfo/pretty-std-collections.rs +++ b/src/test/debuginfo/pretty-std-collections.rs @@ -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(len: 3) = {3, 5, 7} +// gdb-check:$1 = BTreeSet(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(len: 3) = {[3] = 3, [5] = 7, [7] = 4} +// gdb-check:$2 = BTreeMap(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(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(); diff --git a/src/test/run-pass/const-int-conversion.rs b/src/test/run-pass/const-int-conversion.rs index 790c62288d38b..e199c43858521 100644 --- a/src/test/run-pass/const-int-conversion.rs +++ b/src/test/run-pass/const-int-conversion.rs @@ -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]); diff --git a/src/test/run-pass/inherit-env.rs b/src/test/run-pass/inherit-env.rs new file mode 100644 index 0000000000000..856d3a5f72d34 --- /dev/null +++ b/src/test/run-pass/inherit-env.rs @@ -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); + } +} + diff --git a/src/test/run-pass/issues/issue-52169.rs b/src/test/run-pass/issues/issue-52169.rs index 19c0f51d235bc..c4ed534cc20ec 100644 --- a/src/test/run-pass/issues/issue-52169.rs +++ b/src/test/run-pass/issues/issue-52169.rs @@ -9,7 +9,6 @@ // except according to those terms. // run-pass -#![feature(macro_literal_matcher)] macro_rules! a { ($i:literal) => { "right" }; diff --git a/src/test/run-pass/macros/macro-literal.rs b/src/test/run-pass/macros/macro-literal.rs index ecbb47757d11e..de268e3388a5e 100644 --- a/src/test/run-pass/macros/macro-literal.rs +++ b/src/test/run-pass/macros/macro-literal.rs @@ -9,7 +9,6 @@ // except according to those terms. // run-pass -#![feature(macro_literal_matcher)] macro_rules! mtester { ($l:literal) => { diff --git a/src/test/run-pass/string-box-error.rs b/src/test/run-pass/string-box-error.rs index a80d9a0593566..5d8a664b93dad 100644 --- a/src/test/run-pass/string-box-error.rs +++ b/src/test/run-pass/string-box-error.rs @@ -8,7 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// Ensure that both `Box` and `Box` can be obtained from `String`. +// Ensure that both `Box` and `Box` can be +// obtained from `String`. use std::error::Error; diff --git a/src/test/run-pass/unsized-locals/unsized-exprs.rs b/src/test/run-pass/unsized-locals/unsized-exprs.rs index 4b988f1e72d5a..bc64fcdec2e39 100644 --- a/src/test/run-pass/unsized-locals/unsized-exprs.rs +++ b/src/test/run-pass/unsized-locals/unsized-exprs.rs @@ -34,4 +34,5 @@ fn main() { udrop::<[u8]>((*foo())); udrop::<[u8]>((*tfoo()).1); *afoo() + 42; + udrop as fn([u8]); } diff --git a/src/test/ui/consts/auxiliary/const_fn_lib.rs b/src/test/ui/consts/auxiliary/const_fn_lib.rs index 5063c8d1d1f54..72369aae97ce3 100644 --- a/src/test/ui/consts/auxiliary/const_fn_lib.rs +++ b/src/test/ui/consts/auxiliary/const_fn_lib.rs @@ -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 +} diff --git a/src/test/ui/consts/const-int-conversion.rs b/src/test/ui/consts/const-int-conversion.rs index 0abe6b4a1e49f..2a20f0df15ca2 100644 --- a/src/test/ui/consts/const-int-conversion.rs +++ b/src/test/ui/consts/const-int-conversion.rs @@ -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()); diff --git a/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs b/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs new file mode 100644 index 0000000000000..c7617c9c7ad03 --- /dev/null +++ b/src/test/ui/consts/const_fn_return_nested_fn_ptr.rs @@ -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()(); +} diff --git a/src/test/ui/feature-gates/feature-gate-macro-literal-matcher.rs b/src/test/ui/feature-gates/feature-gate-macro-literal-matcher.rs deleted file mode 100644 index db5cca193ab4e..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-macro-literal-matcher.rs +++ /dev/null @@ -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 or the MIT license -// , 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"); -} diff --git a/src/test/ui/feature-gates/feature-gate-macro-literal-matcher.stderr b/src/test/ui/feature-gates/feature-gate-macro-literal-matcher.stderr deleted file mode 100644 index f714b916966a1..0000000000000 --- a/src/test/ui/feature-gates/feature-gate-macro-literal-matcher.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/imports/auxiliary/issue-56125.rs b/src/test/ui/imports/auxiliary/issue-56125.rs index 0ff407756b3ae..8e0797582970d 100644 --- a/src/test/ui/imports/auxiliary/issue-56125.rs +++ b/src/test/ui/imports/auxiliary/issue-56125.rs @@ -1,3 +1,5 @@ +pub mod issue_56125 {} + pub mod last_segment { pub mod issue_56125 {} } diff --git a/src/test/ui/imports/issue-56125.rs b/src/test/ui/imports/issue-56125.rs index 4baeb8a34dd76..843b52f18435e 100644 --- a/src/test/ui/imports/issue-56125.rs +++ b/src/test/ui/imports/issue-56125.rs @@ -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() {} diff --git a/src/test/ui/imports/issue-56125.stderr b/src/test/ui/imports/issue-56125.stderr index 096d5be97f0e0..b1292ef8f783e 100644 --- a/src/test/ui/imports/issue-56125.stderr +++ b/src/test/ui/imports/issue-56125.stderr @@ -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`. diff --git a/src/test/ui/issues/issue-30355.nll.stderr b/src/test/ui/issues/issue-30355.nll.stderr deleted file mode 100644 index fdf8157dcf833..0000000000000 --- a/src/test/ui/issues/issue-30355.nll.stderr +++ /dev/null @@ -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`. diff --git a/src/test/ui/issues/issue-30355.rs b/src/test/ui/issues/issue-30355.rs index ee19d04031893..8d5eac06c4379 100644 --- a/src/test/ui/issues/issue-30355.rs +++ b/src/test/ui/issues/issue-30355.rs @@ -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() {} diff --git a/src/test/ui/issues/issue-30355.stderr b/src/test/ui/issues/issue-30355.stderr index 7e843688035af..1b55f20e6b431 100644 --- a/src/test/ui/issues/issue-30355.stderr +++ b/src/test/ui/issues/issue-30355.stderr @@ -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) - | ^^ - -error[E0507]: cannot move out of borrowed content - --> $DIR/issue-30355.rs:15:8 - | -LL | &X(*Y) - | ^^ cannot move out of borrowed content + = help: the trait `std::marker::Sized` is not implemented for `[u8]` + = note: to learn more, visit + = note: all function arguments must have a statically known size + = help: unsized locals are gated as an unstable feature -error: aborting due to 3 previous errors +error: aborting due to previous error -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`. diff --git a/src/test/ui/issues/issue-34209.rs b/src/test/ui/issues/issue-34209.rs index b3cb7d4cc3053..86eb624edcac1 100644 --- a/src/test/ui/issues/issue-34209.rs +++ b/src/test/ui/issues/issue-34209.rs @@ -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` } } diff --git a/src/test/ui/issues/issue-34209.stderr b/src/test/ui/issues/issue-34209.stderr index 0dfdd8b588634..d5a5647422f41 100644 --- a/src/test/ui/issues/issue-34209.stderr +++ b/src/test/ui/issues/issue-34209.stderr @@ -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: `::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`. diff --git a/src/test/ui/issues/issue-45829/import-self.rs b/src/test/ui/issues/issue-45829/import-self.rs index 8b13ffd0076d5..eb5fb458d8279 100644 --- a/src/test/ui/issues/issue-45829/import-self.rs +++ b/src/test/ui/issues/issue-45829/import-self.rs @@ -19,4 +19,7 @@ use foo as self; use foo::self; +use foo::A; +use foo::{self as A}; + fn main() {} diff --git a/src/test/ui/issues/issue-45829/import-self.stderr b/src/test/ui/issues/issue-45829/import-self.stderr index 985dc4e7131cf..55e51952a8804 100644 --- a/src/test/ui/issues/issue-45829/import-self.stderr +++ b/src/test/ui/issues/issue-45829/import-self.stderr @@ -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}; + | ^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors -Some errors occurred: E0255, E0429. -For more information about an error, try `rustc --explain E0255`. +Some errors occurred: E0252, E0255, E0429. +For more information about an error, try `rustc --explain E0252`. diff --git a/src/test/ui/privacy/restricted/relative-2018.rs b/src/test/ui/privacy/restricted/relative-2018.rs new file mode 100644 index 0000000000000..69b7c1e4d4f3c --- /dev/null +++ b/src/test/ui/privacy/restricted/relative-2018.rs @@ -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() {} diff --git a/src/test/ui/privacy/restricted/relative-2018.stderr b/src/test/ui/privacy/restricted/relative-2018.stderr new file mode 100644 index 0000000000000..61effc463e98f --- /dev/null +++ b/src/test/ui/privacy/restricted/relative-2018.stderr @@ -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 + diff --git a/src/test/ui/suggestions/suggest-variants.rs b/src/test/ui/suggestions/suggest-variants.rs new file mode 100644 index 0000000000000..4a131ed837b87 --- /dev/null +++ b/src/test/ui/suggestions/suggest-variants.rs @@ -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}); +} diff --git a/src/test/ui/suggestions/suggest-variants.stderr b/src/test/ui/suggestions/suggest-variants.stderr new file mode 100644 index 0000000000000..08ae68ea71302 --- /dev/null +++ b/src/test/ui/suggestions/suggest-variants.stderr @@ -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 + diff --git a/src/test/ui/unsized-locals/auxiliary/ufuncs.rs b/src/test/ui/unsized-locals/auxiliary/ufuncs.rs new file mode 100644 index 0000000000000..065563d45a472 --- /dev/null +++ b/src/test/ui/unsized-locals/auxiliary/ufuncs.rs @@ -0,0 +1,3 @@ +#![feature(unsized_locals)] + +pub fn udrop(_x: T) {} diff --git a/src/test/ui/unsized-locals/issue-50940-with-feature.rs b/src/test/ui/unsized-locals/issue-50940-with-feature.rs new file mode 100644 index 0000000000000..3e5d39ab31150 --- /dev/null +++ b/src/test/ui/unsized-locals/issue-50940-with-feature.rs @@ -0,0 +1,7 @@ +#![feature(unsized_locals)] + +fn main() { + struct A(X); + A as fn(str) -> A; + //~^ERROR the size for values of type `str` cannot be known at compilation time +} diff --git a/src/test/ui/unsized-locals/issue-50940-with-feature.stderr b/src/test/ui/unsized-locals/issue-50940-with-feature.stderr new file mode 100644 index 0000000000000..f4f015fa19065 --- /dev/null +++ b/src/test/ui/unsized-locals/issue-50940-with-feature.stderr @@ -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; + | ^ doesn't have a size known at compile-time + | + = help: within `main::A`, the trait `std::marker::Sized` is not implemented for `str` + = note: to learn more, visit + = note: required because it appears within the type `main::A` + = 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`. diff --git a/src/test/ui/unsized-locals/issue-50940.rs b/src/test/ui/unsized-locals/issue-50940.rs new file mode 100644 index 0000000000000..7ba809b7e83e3 --- /dev/null +++ b/src/test/ui/unsized-locals/issue-50940.rs @@ -0,0 +1,5 @@ +fn main() { + struct A(X); + A as fn(str) -> A; + //~^ERROR the size for values of type `str` cannot be known at compilation time +} diff --git a/src/test/ui/unsized-locals/issue-50940.stderr b/src/test/ui/unsized-locals/issue-50940.stderr new file mode 100644 index 0000000000000..9f3669ccf1f15 --- /dev/null +++ b/src/test/ui/unsized-locals/issue-50940.stderr @@ -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; + | ^ 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 + = 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`. diff --git a/src/test/ui/unsized-locals/unsized-exprs.rs b/src/test/ui/unsized-locals/unsized-exprs.rs index 0cf93c78c4abe..8ca88edcb6add 100644 --- a/src/test/ui/unsized-locals/unsized-exprs.rs +++ b/src/test/ui/unsized-locals/unsized-exprs.rs @@ -23,4 +23,6 @@ fn main() { //~^ERROR E0277 udrop::>(A { 0: *foo() }); //~^ERROR E0277 + udrop::>(A(*foo())); + //~^ERROR E0277 } diff --git a/src/test/ui/unsized-locals/unsized-exprs.stderr b/src/test/ui/unsized-locals/unsized-exprs.stderr index eb2016941770c..0ca60e8dea0d9 100644 --- a/src/test/ui/unsized-locals/unsized-exprs.stderr +++ b/src/test/ui/unsized-locals/unsized-exprs.stderr @@ -20,6 +20,17 @@ LL | udrop::>(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(*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 + = 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`. diff --git a/src/test/ui/unsized-locals/unsized-exprs2.rs b/src/test/ui/unsized-locals/unsized-exprs2.rs index ae69893a83577..3fb5a002e0e3c 100644 --- a/src/test/ui/unsized-locals/unsized-exprs2.rs +++ b/src/test/ui/unsized-locals/unsized-exprs2.rs @@ -21,6 +21,4 @@ impl std::ops::Add for A<[u8]> { fn main() { udrop::<[u8]>(foo()[..]); //~^ERROR cannot move out of indexed content - // FIXME: should be error - udrop::>(A(*foo())); } diff --git a/src/test/ui/unsized-locals/unsized-exprs3.rs b/src/test/ui/unsized-locals/unsized-exprs3.rs new file mode 100644 index 0000000000000..2133b01e09480 --- /dev/null +++ b/src/test/ui/unsized-locals/unsized-exprs3.rs @@ -0,0 +1,10 @@ +// aux-build:ufuncs.rs + +extern crate ufuncs; + +use ufuncs::udrop; + +fn main() { + udrop as fn([u8]); + //~^ERROR E0277 +} diff --git a/src/test/ui/unsized-locals/unsized-exprs3.stderr b/src/test/ui/unsized-locals/unsized-exprs3.stderr new file mode 100644 index 0000000000000..42f91a946a851 --- /dev/null +++ b/src/test/ui/unsized-locals/unsized-exprs3.stderr @@ -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 + = 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`.