From 2438cfc755edb27637a928806ecf07878f7d8bde Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 13 Aug 2018 18:03:06 -0700 Subject: [PATCH 01/18] Fix usage of `wasm_target_feature` --- src/librustc_typeck/collect.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 77b02d9ff5bce..02f431dccca6b 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1925,6 +1925,7 @@ fn from_target_feature( Some("mmx_target_feature") => rust_features.mmx_target_feature, Some("sse4a_target_feature") => rust_features.sse4a_target_feature, Some("tbm_target_feature") => rust_features.tbm_target_feature, + Some("wasm_target_feature") => rust_features.wasm_target_feature, Some(name) => bug!("unknown target feature gate {}", name), None => true, }; From e390182602a099114730a1f889d1131a6c305f55 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Mon, 13 Aug 2018 22:45:02 -0400 Subject: [PATCH 02/18] [nll] add regression test for issue #27868 --- src/test/ui/nll/issue-27868.rs | 40 ++++++++++++++++++++++++++++++ src/test/ui/nll/issue-27868.stderr | 18 ++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 src/test/ui/nll/issue-27868.rs create mode 100644 src/test/ui/nll/issue-27868.stderr diff --git a/src/test/ui/nll/issue-27868.rs b/src/test/ui/nll/issue-27868.rs new file mode 100644 index 0000000000000..022917a5556e6 --- /dev/null +++ b/src/test/ui/nll/issue-27868.rs @@ -0,0 +1,40 @@ +// 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. + +// Regression test for issue #27868 + +#![feature(nll)] + +use std::ops::AddAssign; + +struct MyVec(Vec); + +impl Drop for MyVec { + fn drop(&mut self) { + println!("Being dropped."); + } +} + +impl AddAssign for MyVec { + fn add_assign(&mut self, _elem: T) { + println!("In add_assign."); + } +} + +fn main() { + let mut vec = MyVec(vec![0]); + let mut vecvec = vec![vec]; + + vecvec[0] += { + vecvec = vec![]; + //~^ ERROR cannot assign to `vecvec` because it is borrowed [E0506] + 0 + }; +} diff --git a/src/test/ui/nll/issue-27868.stderr b/src/test/ui/nll/issue-27868.stderr new file mode 100644 index 0000000000000..a376829e37b8c --- /dev/null +++ b/src/test/ui/nll/issue-27868.stderr @@ -0,0 +1,18 @@ +error[E0506]: cannot assign to `vecvec` because it is borrowed + --> $DIR/issue-27868.rs:36:9 + | +LL | vecvec[0] += { + | ------ + | | + | _____borrow of `vecvec` occurs here + | | +LL | | vecvec = vec![]; + | | ^^^^^^ assignment to borrowed `vecvec` occurs here +LL | | //~^ ERROR cannot assign to `vecvec` because it is borrowed [E0506] +LL | | 0 +LL | | }; + | |_____- borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0506`. From a7e877ebdd0c0dc7141b8bb898dd4aa4196f8c5f Mon Sep 17 00:00:00 2001 From: memoryruins Date: Tue, 14 Aug 2018 10:25:54 -0400 Subject: [PATCH 03/18] Add regression test for issue #48697 #48697 --- src/test/ui/nll/issue-48697.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/test/ui/nll/issue-48697.rs diff --git a/src/test/ui/nll/issue-48697.rs b/src/test/ui/nll/issue-48697.rs new file mode 100644 index 0000000000000..69ff82e16a1bf --- /dev/null +++ b/src/test/ui/nll/issue-48697.rs @@ -0,0 +1,24 @@ +// 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. + +// Regression test for #48697 + +// compile-pass + +#![feature(nll)] + +fn foo(x: &i32) -> &i32 { + let z = 4; + let f = &|y| y; + let k = f(&z); + f(x) +} + +fn main() {} From f4bed39c5c68e345e1d816f9af7cbf6b666bf717 Mon Sep 17 00:00:00 2001 From: memoryruins Date: Tue, 14 Aug 2018 10:26:47 -0400 Subject: [PATCH 04/18] Add regression test for issue #30104 #30104 --- src/test/ui/nll/issue-30104.rs | 52 ++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 src/test/ui/nll/issue-30104.rs diff --git a/src/test/ui/nll/issue-30104.rs b/src/test/ui/nll/issue-30104.rs new file mode 100644 index 0000000000000..64c32a55d0496 --- /dev/null +++ b/src/test/ui/nll/issue-30104.rs @@ -0,0 +1,52 @@ +// 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. + +// Regression test for #30104 + +// compile-pass + +#![feature(nll)] + +use std::ops::{Deref, DerefMut}; + +fn box_two_field(v: &mut Box<(i32, i32)>) { + let _a = &mut v.0; + let _b = &mut v.1; +} + +fn box_destructure(v: &mut Box<(i32, i32)>) { + let (ref mut _head, ref mut _tail) = **v; +} + +struct Wrap(T); + +impl Deref for Wrap { + type Target = T; + fn deref(&self) -> &T { + &self.0 + } +} + +impl DerefMut for Wrap { + fn deref_mut(&mut self) -> &mut T { + &mut self.0 + } +} + +fn smart_two_field(v: &mut Wrap<(i32, i32)>) { + let _a = &mut v.0; + let _b = &mut v.1; +} + +fn smart_destructure(v: &mut Wrap<(i32, i32)>) { + let (ref mut _head, ref mut _tail) = **v; +} + +fn main() {} From 8defd152b35f6b397445ce420f22227a5e623a1a Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 14 Aug 2018 18:46:04 +0200 Subject: [PATCH 05/18] `{to,from}_{ne,le,be}_bytes` for unsigned integer types Same as https://github.com/rust-lang/rust/pull/51919 did for signed integers. Tracking issue: https://github.com/rust-lang/rust/issues/52963 --- src/libcore/num/mod.rs | 104 ++++++++++++++++++++++++++++++++++------- 1 file changed, 88 insertions(+), 16 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index eb63966354b86..feaedf4b90912 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -3568,47 +3568,119 @@ $EndFeature, " } } - /// Return the memory representation of this integer as a byte array. + /// Return the memory representation of this integer as a byte array in + /// big-endian (network) byte order. /// - /// The target platform’s native endianness is used. - /// Portable code likely wants to use this after [`to_be`] or [`to_le`]. + /// # Examples /// - /// [`to_be`]: #method.to_be - /// [`to_le`]: #method.to_le + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let bytes = 0x12345678i32.to_be_bytes(); + /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "52963")] + #[inline] + pub fn to_be_bytes(self) -> [u8; mem::size_of::()] { + self.to_be().to_ne_bytes() + } + + /// Return the memory representation of this integer as a byte array in + /// little-endian byte order. /// /// # Examples /// /// ``` /// #![feature(int_to_from_bytes)] /// - /// let bytes = 0x1234_5678_u32.to_be().to_bytes(); - /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); + /// let bytes = 0x12345678i32.to_le_bytes(); + /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]); /// ``` #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] - pub fn to_bytes(self) -> [u8; mem::size_of::()] { + pub fn to_le_bytes(self) -> [u8; mem::size_of::()] { + self.to_le().to_ne_bytes() + } + + /// Return the memory representation of this integer as a byte array in + /// native byte order. + /// + /// As the target platform's native endianness is used, portable code + /// should use [`to_be_bytes`] or [`to_le_bytes`], as appropriate, + /// instead. + /// + /// [`to_be_bytes`]: #method.to_be_bytes + /// [`to_le_bytes`]: #method.to_le_bytes + /// + /// # Examples + /// + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let bytes = i32::min_value().to_be().to_ne_bytes(); + /// assert_eq!(bytes, [0x80, 0, 0, 0]); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "52963")] + #[inline] + pub fn to_ne_bytes(self) -> [u8; mem::size_of::()] { unsafe { mem::transmute(self) } } - /// Create an integer value from its memory representation as a byte array. + /// Create an integer value from its representation as a byte array in + /// big endian. + /// + /// # Examples + /// + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let int = i32::from_be_bytes([0x12, 0x34, 0x56, 0x78]); + /// assert_eq!(int, 0x12_34_56_78); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "52963")] + #[inline] + pub fn from_be_bytes(bytes: [u8; mem::size_of::()]) -> Self { + Self::from_be(Self::from_ne_bytes(bytes)) + } + + /// Create an integer value from its representation as a byte array in + /// little endian. + /// + /// # Examples + /// + /// ``` + /// #![feature(int_to_from_bytes)] + /// + /// let int = i32::from_le_bytes([0x12, 0x34, 0x56, 0x78]); + /// assert_eq!(int, 0x78_56_34_12); + /// ``` + #[unstable(feature = "int_to_from_bytes", issue = "52963")] + #[inline] + pub fn from_le_bytes(bytes: [u8; mem::size_of::()]) -> Self { + Self::from_le(Self::from_ne_bytes(bytes)) + } + + /// Create an integer value from its memory representation as a byte + /// array in native endianness. /// - /// The target platform’s native endianness is used. - /// Portable code likely wants to use [`to_be`] or [`to_le`] after this. + /// As the target platform's native endianness is used, portable code + /// likely wants to use [`from_be_bytes`] or [`from_le_bytes`], as + /// appropriate instead. /// - /// [`to_be`]: #method.to_be - /// [`to_le`]: #method.to_le + /// [`from_be_bytes`]: #method.from_be_bytes + /// [`from_le_bytes`]: #method.from_le_bytes /// /// # Examples /// /// ``` /// #![feature(int_to_from_bytes)] /// - /// let int = u32::from_be(u32::from_bytes([0x12, 0x34, 0x56, 0x78])); - /// assert_eq!(int, 0x1234_5678_u32); + /// let int = i32::from_be(i32::from_ne_bytes([0x80, 0, 0, 0])); + /// assert_eq!(int, i32::min_value()); /// ``` #[unstable(feature = "int_to_from_bytes", issue = "52963")] #[inline] - pub fn from_bytes(bytes: [u8; mem::size_of::()]) -> Self { + pub fn from_ne_bytes(bytes: [u8; mem::size_of::()]) -> Self { unsafe { mem::transmute(bytes) } } } From 0d0c08f9bb75002138ed0b69b0058099ec41ccd1 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 15 Aug 2018 01:38:00 +0900 Subject: [PATCH 06/18] pretty printing for btreemap --- src/etc/debugger_pretty_printers_common.py | 21 ++++++++++++++ src/etc/gdb_rust_pretty_printing.py | 30 ++++++++++++++++++++ src/test/debuginfo/pretty-std-collections.rs | 12 +++++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/etc/debugger_pretty_printers_common.py b/src/etc/debugger_pretty_printers_common.py index e64d863717da0..1797f6708ac5b 100644 --- a/src/etc/debugger_pretty_printers_common.py +++ b/src/etc/debugger_pretty_printers_common.py @@ -49,6 +49,7 @@ TYPE_KIND_OS_STRING = 18 TYPE_KIND_STD_VECDEQUE = 19 TYPE_KIND_STD_BTREESET = 20 +TYPE_KIND_STD_BTREEMAP = 21 ENCODED_ENUM_PREFIX = "RUST$ENCODED$ENUM$" ENUM_DISR_FIELD_NAME = "RUST$ENUM$DISR" @@ -75,6 +76,9 @@ # std::collections::BTreeSet<> related constants STD_BTREESET_FIELD_NAMES = ["map"] +# std::collections::BTreeMap<> related constants +STD_BTREEMAP_FIELD_NAMES = ["root", "length"] + # std::String related constants STD_STRING_FIELD_NAMES = ["vec"] @@ -184,6 +188,11 @@ def __classify_struct(self): self.__conforms_to_field_layout(STD_BTREESET_FIELD_NAMES)): return TYPE_KIND_STD_BTREESET + # STD COLLECTION BTREEMAP + if (unqualified_type_name.startswith("BTreeMap<") and + self.__conforms_to_field_layout(STD_BTREEMAP_FIELD_NAMES)): + return TYPE_KIND_STD_BTREEMAP + # STD STRING if (unqualified_type_name.startswith("String") and self.__conforms_to_field_layout(STD_STRING_FIELD_NAMES)): @@ -380,6 +389,18 @@ def extract_length_and_ptr_from_std_btreeset(vec_val): 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 fae1fd0cac30d..216915dba5fe7 100755 --- a/src/etc/gdb_rust_pretty_printing.py +++ b/src/etc/gdb_rust_pretty_printing.py @@ -130,6 +130,9 @@ def rust_pretty_printer_lookup_function(gdb_val): if type_kind == rustpp.TYPE_KIND_STD_BTREESET: return RustStdBTreeSetPrinter(val) + if type_kind == rustpp.TYPE_KIND_STD_BTREEMAP: + return RustStdBTreeMapPrinter(val) + if type_kind == rustpp.TYPE_KIND_STD_STRING: return RustStdStringPrinter(val) @@ -325,6 +328,32 @@ def children(self): yield (str(index), gdb_ptr[index]) +class RustStdBTreeMapPrinter(object): + def __init__(self, val): + self.__val = val + + @staticmethod + 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)) + + def children(self): + (length, data_ptr) = \ + rustpp.extract_length_and_ptr_from_std_btreemap(self.__val) + keys = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(3) + keys_ptr = keys.get_wrapped_value() + vals = GdbValue(data_ptr.get_wrapped_value().dereference()).get_child_at_index(4) + vals_ptr = vals.get_wrapped_value() + for index in xrange(length): + yield (str(index), keys_ptr[index]) + yield (str(index), vals_ptr[index]) + + class RustStdStringPrinter(object): def __init__(self, val): self.__val = val @@ -338,6 +367,7 @@ def to_string(self): def display_hint(self): return "string" + class RustOsStringPrinter(object): def __init__(self, val): self.__val = val diff --git a/src/test/debuginfo/pretty-std-collections.rs b/src/test/debuginfo/pretty-std-collections.rs index 18d73bf5677bc..8e37a884b34bb 100644 --- a/src/test/debuginfo/pretty-std-collections.rs +++ b/src/test/debuginfo/pretty-std-collections.rs @@ -22,11 +22,15 @@ // gdb-command: print btree_set // gdb-check:$1 = BTreeSet(len: 3) = {3, 5, 7} +// gdb-command: print btree_map +// gdb-check:$2 = BTreeMap(len: 3) = {[3] = 3, [5] = 7, [7] = 4} + // gdb-command: print vec_deque -// gdb-check:$2 = VecDeque(len: 3, cap: 8) = {5, 3, 7} +// gdb-check:$3 = VecDeque(len: 3, cap: 8) = {5, 3, 7} #![allow(unused_variables)] use std::collections::BTreeSet; +use std::collections::BTreeMap; use std::collections::VecDeque; @@ -38,6 +42,12 @@ fn main() { btree_set.insert(3); btree_set.insert(7); + // BTreeMap + let mut btree_map = BTreeMap::new(); + btree_map.insert(5, 7); + btree_map.insert(3, 3); + btree_map.insert(7, 4); + // VecDeque let mut vec_deque = VecDeque::new(); vec_deque.push_back(5); From 5a0a38a46f325512f00809ba5406c1fd6b3dae49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Aug 2018 12:30:50 -0700 Subject: [PATCH 07/18] Do not suggest conversion method that is already there --- src/librustc_typeck/check/mod.rs | 10 ++++++++-- src/test/ui/issues/issue-53348.rs | 26 ++++++++++++++++++++++++++ src/test/ui/issues/issue-53348.stderr | 12 ++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/issues/issue-53348.rs create mode 100644 src/test/ui/issues/issue-53348.stderr diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 43edb23504480..4fac11189a400 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4629,8 +4629,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let methods = self.get_conversion_methods(expr.span, expected, found); if let Ok(expr_text) = self.sess().codemap().span_to_snippet(expr.span) { let suggestions = iter::repeat(expr_text).zip(methods.iter()) - .map(|(receiver, method)| format!("{}.{}()", receiver, method.ident)) - .collect::>(); + .filter_map(|(receiver, method)| { + let method_call = format!(".{}()", method.ident); + if receiver.ends_with(&method_call) { + None // do not suggest code that is already there (#53348) + } else { + Some(format!("{}{}", receiver, method_call)) + } + }) .collect::>(); if !suggestions.is_empty() { err.span_suggestions(expr.span, "try using a conversion method", suggestions); } diff --git a/src/test/ui/issues/issue-53348.rs b/src/test/ui/issues/issue-53348.rs new file mode 100644 index 0000000000000..46ab07dad6e47 --- /dev/null +++ b/src/test/ui/issues/issue-53348.rs @@ -0,0 +1,26 @@ +// 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. + +fn main() { + let mut v = vec!["hello", "this", "is", "a", "test"]; + + let v2 = Vec::new(); + + v.into_iter().map(|s|s.to_owned()).collect::>(); + + let mut a = String::new(); + for i in v { + a = *i.to_string(); + //~^ ERROR mismatched types + //~| NOTE expected struct `std::string::String`, found str + //~| NOTE expected type + v2.push(a); + } +} diff --git a/src/test/ui/issues/issue-53348.stderr b/src/test/ui/issues/issue-53348.stderr new file mode 100644 index 0000000000000..9aab4928ffa57 --- /dev/null +++ b/src/test/ui/issues/issue-53348.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/issue-53348.rs:20:13 + | +LL | a = *i.to_string(); + | ^^^^^^^^^^^^^^ expected struct `std::string::String`, found str + | + = note: expected type `std::string::String` + found type `str` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From dd9f84f2d3c01d87b8e4d6f96a9c4b46d8e22992 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 15 Aug 2018 23:26:59 +0200 Subject: [PATCH 08/18] Removed `ignore-test-compare-mode-nll` from borrowck-closures-unique.rs by strengthening the tests there. In almost all cases the strengthening amount to just encoding a use that models the original lexical lifetime. A more invasive revision was made in one case where it seems the actual issue is MIR-borrowck's greater "knowledge" of unreachable code in the control flow... --- .../borrowck-closures-unique.nll.stderr | 54 +++++++++++++++++++ .../ui/borrowck/borrowck-closures-unique.rs | 21 ++++++-- .../borrowck/borrowck-closures-unique.stderr | 23 ++++++-- 3 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/borrowck/borrowck-closures-unique.nll.stderr diff --git a/src/test/ui/borrowck/borrowck-closures-unique.nll.stderr b/src/test/ui/borrowck/borrowck-closures-unique.nll.stderr new file mode 100644 index 0000000000000..17519ccb1438d --- /dev/null +++ b/src/test/ui/borrowck/borrowck-closures-unique.nll.stderr @@ -0,0 +1,54 @@ +error[E0500]: closure requires unique access to `x` but it is already borrowed + --> $DIR/borrowck-closures-unique.rs:36:14 + | +LL | let c1 = || get(x); + | -- - first borrow occurs due to use of `x` in closure + | | + | borrow occurs here +LL | let c2 = || set(x); //~ ERROR closure requires unique access to `x` + | ^^ - second borrow occurs due to use of `x` in closure + | | + | closure construction occurs here +LL | c1; + | -- borrow later used here + +error[E0500]: closure requires unique access to `x` but it is already borrowed + --> $DIR/borrowck-closures-unique.rs:42:14 + | +LL | let c1 = || get(x); + | -- - first borrow occurs due to use of `x` in closure + | | + | borrow occurs here +LL | let c2 = || { get(x); set(x); }; //~ ERROR closure requires unique access to `x` + | ^^ - second borrow occurs due to use of `x` in closure + | | + | closure construction occurs here +LL | c1; + | -- borrow later used here + +error[E0524]: two closures require unique access to `x` at the same time + --> $DIR/borrowck-closures-unique.rs:48:14 + | +LL | let c1 = || set(x); + | -- - first borrow occurs due to use of `x` in closure + | | + | first closure is constructed here +LL | let c2 = || set(x); //~ ERROR two closures require unique access to `x` at the same time + | ^^ - second borrow occurs due to use of `x` in closure + | | + | second closure is constructed here +LL | c1; + | -- borrow later used here + +error[E0594]: cannot assign to `x`, as it is not declared as mutable + --> $DIR/borrowck-closures-unique.rs:57:38 + | +LL | fn e(x: &'static mut isize) { + | - help: consider changing this to be mutable: `mut x` +LL | let c1 = |y: &'static mut isize| x = y; //~ ERROR closure cannot assign to immutable argument + | ^^^^^ cannot assign + +error: aborting due to 4 previous errors + +Some errors occurred: E0500, E0524, E0594. +For more information about an error, try `rustc --explain E0500`. diff --git a/src/test/ui/borrowck/borrowck-closures-unique.rs b/src/test/ui/borrowck/borrowck-closures-unique.rs index 9a74f188a545f..caf5785f481c2 100644 --- a/src/test/ui/borrowck/borrowck-closures-unique.rs +++ b/src/test/ui/borrowck/borrowck-closures-unique.rs @@ -8,14 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Tests that a closure which requires mutable access to the referent // of an `&mut` requires a "unique" borrow -- that is, the variable to // be borrowed (here, `x`) will not be borrowed *mutably*, but // may be *immutable*, but we cannot allow // multiple borrows. + + fn get(x: &isize) -> isize { *x } @@ -27,25 +27,40 @@ fn set(x: &mut isize) -> isize { fn a(x: &mut isize) { let c1 = || get(x); let c2 = || get(x); + c1(); + c2(); } fn b(x: &mut isize) { let c1 = || get(x); let c2 = || set(x); //~ ERROR closure requires unique access to `x` + c1; } fn c(x: &mut isize) { let c1 = || get(x); let c2 = || { get(x); set(x); }; //~ ERROR closure requires unique access to `x` + c1; } fn d(x: &mut isize) { let c1 = || set(x); let c2 = || set(x); //~ ERROR two closures require unique access to `x` at the same time + c1; +} + +// This test was originally encoded in the form shown as `fn f` below. +// However, since MIR-borrowck and thus NLL takes more control-flow information +// into account, it was necessary to change the test in order to witness the +// same (expected) error under both AST-borrowck and NLL. +fn e(x: &'static mut isize) { + let c1 = |y: &'static mut isize| x = y; //~ ERROR closure cannot assign to immutable argument + c1; } -fn e(x: &mut isize) { +fn f(x: &'static mut isize) { let c1 = || x = panic!(); //~ ERROR closure cannot assign to immutable argument + c1; } fn main() { diff --git a/src/test/ui/borrowck/borrowck-closures-unique.stderr b/src/test/ui/borrowck/borrowck-closures-unique.stderr index 27163bde34f6a..cfcb81b31e700 100644 --- a/src/test/ui/borrowck/borrowck-closures-unique.stderr +++ b/src/test/ui/borrowck/borrowck-closures-unique.stderr @@ -1,5 +1,5 @@ error[E0500]: closure requires unique access to `x` but it is already borrowed - --> $DIR/borrowck-closures-unique.rs:34:14 + --> $DIR/borrowck-closures-unique.rs:36:14 | LL | let c1 = || get(x); | -- - previous borrow occurs due to use of `x` in closure @@ -9,11 +9,12 @@ LL | let c2 = || set(x); //~ ERROR closure requires unique access to `x` | ^^ - borrow occurs due to use of `x` in closure | | | closure construction occurs here +LL | c1; LL | } | - borrow ends here error[E0500]: closure requires unique access to `x` but it is already borrowed - --> $DIR/borrowck-closures-unique.rs:39:14 + --> $DIR/borrowck-closures-unique.rs:42:14 | LL | let c1 = || get(x); | -- - previous borrow occurs due to use of `x` in closure @@ -23,11 +24,12 @@ LL | let c2 = || { get(x); set(x); }; //~ ERROR closure requires unique acce | ^^ - borrow occurs due to use of `x` in closure | | | closure construction occurs here +LL | c1; LL | } | - borrow ends here error[E0524]: two closures require unique access to `x` at the same time - --> $DIR/borrowck-closures-unique.rs:44:14 + --> $DIR/borrowck-closures-unique.rs:48:14 | LL | let c1 = || set(x); | -- - previous borrow occurs due to use of `x` in closure @@ -37,11 +39,22 @@ LL | let c2 = || set(x); //~ ERROR two closures require unique access to `x` | ^^ - borrow occurs due to use of `x` in closure | | | second closure is constructed here +LL | c1; LL | } | - borrow from first closure ends here error[E0595]: closure cannot assign to immutable argument `x` - --> $DIR/borrowck-closures-unique.rs:48:14 + --> $DIR/borrowck-closures-unique.rs:57:14 + | +LL | let c1 = |y: &'static mut isize| x = y; //~ ERROR closure cannot assign to immutable argument + | ^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow mutably +help: consider removing the `&mut`, as it is an immutable binding to a mutable reference + | +LL | x //~ ERROR closure cannot assign to immutable argument + | ^ + +error[E0595]: closure cannot assign to immutable argument `x` + --> $DIR/borrowck-closures-unique.rs:62:14 | LL | let c1 = || x = panic!(); //~ ERROR closure cannot assign to immutable argument | ^^ cannot borrow mutably @@ -50,7 +63,7 @@ help: consider removing the `&mut`, as it is an immutable binding to a mutable r LL | x //~ ERROR closure cannot assign to immutable argument | ^ -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors Some errors occurred: E0500, E0524, E0595. For more information about an error, try `rustc --explain E0500`. From fb3ccb2aa2e67a784cd106eae87ae29a1688fdee Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 15 Aug 2018 23:31:00 +0200 Subject: [PATCH 09/18] Removed `ignore-test-compare-mode-nll` from borrowck-closures-two-mut-fail.rs by strengthening the tests there. --- .../borrowck-closures-two-mut-fail.nll.stderr | 75 +++++++++++++++++++ .../borrowck-closures-two-mut-fail.rs | 13 +++- .../borrowck-closures-two-mut-fail.stderr | 15 ++-- 3 files changed, 93 insertions(+), 10 deletions(-) create mode 100644 src/test/ui/borrowck/borrowck-closures-two-mut-fail.nll.stderr diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut-fail.nll.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut-fail.nll.stderr new file mode 100644 index 0000000000000..c96799c85f206 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-closures-two-mut-fail.nll.stderr @@ -0,0 +1,75 @@ +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut-fail.rs:26:24 + | +LL | let c1 = to_fn_mut(|| x = 4); + | -- - first borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable more than once + | ^^ - second borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +LL | c1; + | -- borrow later used here + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut-fail.rs:37:24 + | +LL | let c1 = to_fn_mut(|| set(&mut x)); + | -- - first borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once + | ^^ - second borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +LL | c1; + | -- borrow later used here + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut-fail.rs:44:24 + | +LL | let c1 = to_fn_mut(|| x = 5); + | -- - first borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once + | ^^ - second borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +LL | c1; + | -- borrow later used here + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut-fail.rs:51:24 + | +LL | let c1 = to_fn_mut(|| x = 5); + | -- - first borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) + | ^^ - second borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +LL | //~^ ERROR cannot borrow `x` as mutable more than once +LL | c1; + | -- borrow later used here + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut-fail.rs:63:24 + | +LL | let c1 = to_fn_mut(|| set(&mut *x.f)); + | -- - first borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| set(&mut *x.f)); + | ^^ - second borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +LL | //~^ ERROR cannot borrow `x` as mutable more than once +LL | c1; + | -- borrow later used here + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut-fail.rs b/src/test/ui/borrowck/borrowck-closures-two-mut-fail.rs index 6a1b786f52843..66ebd346dab62 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut-fail.rs +++ b/src/test/ui/borrowck/borrowck-closures-two-mut-fail.rs @@ -8,22 +8,23 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Tests that two closures cannot simultaneously have mutable // access to the variable, whether that mutable access be used // for direct assignment or for taking mutable ref. Issue #6801. -// ignore-compare-mode-nll - #![feature(box_syntax)] + + + + fn to_fn_mut(f: F) -> F { f } fn a() { let mut x = 3; let c1 = to_fn_mut(|| x = 4); let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable more than once + c1; } fn set(x: &mut isize) { @@ -34,12 +35,14 @@ fn b() { let mut x = 3; let c1 = to_fn_mut(|| set(&mut x)); let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once + c1; } fn c() { let mut x = 3; let c1 = to_fn_mut(|| x = 5); let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once + c1; } fn d() { @@ -47,6 +50,7 @@ fn d() { let c1 = to_fn_mut(|| x = 5); let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) //~^ ERROR cannot borrow `x` as mutable more than once + c1; } fn g() { @@ -58,6 +62,7 @@ fn g() { let c1 = to_fn_mut(|| set(&mut *x.f)); let c2 = to_fn_mut(|| set(&mut *x.f)); //~^ ERROR cannot borrow `x` as mutable more than once + c1; } fn main() { diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr index bea32f6be9964..59104cc4be9b9 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr +++ b/src/test/ui/borrowck/borrowck-closures-two-mut-fail.stderr @@ -9,11 +9,12 @@ LL | let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable mo | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here +LL | c1; LL | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut-fail.rs:36:24 + --> $DIR/borrowck-closures-two-mut-fail.rs:37:24 | LL | let c1 = to_fn_mut(|| set(&mut x)); | -- - previous borrow occurs due to use of `x` in closure @@ -23,11 +24,12 @@ LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as muta | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here +LL | c1; LL | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut-fail.rs:42:24 + --> $DIR/borrowck-closures-two-mut-fail.rs:44:24 | LL | let c1 = to_fn_mut(|| x = 5); | -- - previous borrow occurs due to use of `x` in closure @@ -37,11 +39,12 @@ LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as muta | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here +LL | c1; LL | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut-fail.rs:48:24 + --> $DIR/borrowck-closures-two-mut-fail.rs:51:24 | LL | let c1 = to_fn_mut(|| x = 5); | -- - previous borrow occurs due to use of `x` in closure @@ -51,12 +54,12 @@ LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nes | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -LL | //~^ ERROR cannot borrow `x` as mutable more than once +... LL | } | - first borrow ends here error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut-fail.rs:59:24 + --> $DIR/borrowck-closures-two-mut-fail.rs:63:24 | LL | let c1 = to_fn_mut(|| set(&mut *x.f)); | -- - previous borrow occurs due to use of `x` in closure @@ -66,7 +69,7 @@ LL | let c2 = to_fn_mut(|| set(&mut *x.f)); | ^^ - borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -LL | //~^ ERROR cannot borrow `x` as mutable more than once +... LL | } | - first borrow ends here From f8084c675ed8d43da68dcec67aaccc576894b072 Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 15 Aug 2018 23:33:14 +0200 Subject: [PATCH 10/18] Removed `ignore-test-compare-mode-nll` from hashmap-lifetimes.rs by strengthening the test there. --- src/test/ui/hashmap-lifetimes.nll.stderr | 13 +++++++++++++ src/test/ui/hashmap-lifetimes.rs | 3 ++- src/test/ui/hashmap-lifetimes.stderr | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/hashmap-lifetimes.nll.stderr diff --git a/src/test/ui/hashmap-lifetimes.nll.stderr b/src/test/ui/hashmap-lifetimes.nll.stderr new file mode 100644 index 0000000000000..943b684fe8d77 --- /dev/null +++ b/src/test/ui/hashmap-lifetimes.nll.stderr @@ -0,0 +1,13 @@ +error[E0502]: cannot borrow `my_stuff` as mutable because it is also borrowed as immutable + --> $DIR/hashmap-lifetimes.rs:18:5 + | +LL | let mut it = my_stuff.iter(); + | -------- immutable borrow occurs here +LL | my_stuff.insert(1, 43); //~ ERROR cannot borrow + | ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here +LL | it; + | -- borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/hashmap-lifetimes.rs b/src/test/ui/hashmap-lifetimes.rs index 9418c34cbfdaa..eb7404e7b780b 100644 --- a/src/test/ui/hashmap-lifetimes.rs +++ b/src/test/ui/hashmap-lifetimes.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll + fn main() { let mut my_stuff = std::collections::HashMap::new(); @@ -16,4 +16,5 @@ fn main() { let mut it = my_stuff.iter(); my_stuff.insert(1, 43); //~ ERROR cannot borrow + it; } diff --git a/src/test/ui/hashmap-lifetimes.stderr b/src/test/ui/hashmap-lifetimes.stderr index eb129848ed2d6..187c98ab298b6 100644 --- a/src/test/ui/hashmap-lifetimes.stderr +++ b/src/test/ui/hashmap-lifetimes.stderr @@ -5,6 +5,7 @@ LL | let mut it = my_stuff.iter(); | -------- immutable borrow occurs here LL | my_stuff.insert(1, 43); //~ ERROR cannot borrow | ^^^^^^^^ mutable borrow occurs here +LL | it; LL | } | - immutable borrow ends here From cd89fdbbc95621e27d77e0d53899b29a3f3a738d Mon Sep 17 00:00:00 2001 From: "Felix S. Klock II" Date: Wed, 15 Aug 2018 23:39:30 +0200 Subject: [PATCH 11/18] Removed `ignore-test-compare-mode-nll` from unboxed-closures tests by strengthening the tests (by adding no-op references to the closures doing the borrows after the conflicting borrows, thus forcing the lifetimes to resemble lexical scopes even under NLL). --- .../unboxed-closure-region.nll.stderr | 15 +++++++++++++++ .../ui/unboxed-closures/unboxed-closure-region.rs | 5 +++-- .../unboxed-closure-region.stderr | 1 + .../unboxed-closures-borrow-conflict.nll.stderr | 15 +++++++++++++++ .../unboxed-closures-borrow-conflict.rs | 5 +++-- 5 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr create mode 100644 src/test/ui/unboxed-closures/unboxed-closures-borrow-conflict.nll.stderr diff --git a/src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr b/src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr new file mode 100644 index 0000000000000..6ad57a15465d3 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closure-region.nll.stderr @@ -0,0 +1,15 @@ +error[E0597]: `x` does not live long enough + --> $DIR/unboxed-closure-region.rs:18:12 + | +LL | || x //~ ERROR `x` does not live long enough + | -- ^ borrowed value does not live long enough + | | + | value captured here +LL | }; + | - `x` dropped here while still borrowed +LL | _f; + | -- borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/unboxed-closures/unboxed-closure-region.rs b/src/test/ui/unboxed-closures/unboxed-closure-region.rs index cc635296210a0..da6dbc6e74f86 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-region.rs +++ b/src/test/ui/unboxed-closures/unboxed-closure-region.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Test that an unboxed closure that captures a free variable by // reference cannot escape the region of that variable. + + fn main() { let _f = { let x = 0; || x //~ ERROR `x` does not live long enough }; + _f; } diff --git a/src/test/ui/unboxed-closures/unboxed-closure-region.stderr b/src/test/ui/unboxed-closures/unboxed-closure-region.stderr index a838c3608b9a9..f85f3afff70e8 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-region.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-region.stderr @@ -7,6 +7,7 @@ LL | || x //~ ERROR `x` does not live long enough | capture occurs here LL | }; | - borrowed value only lives until here +LL | _f; LL | } | - borrowed value needs to live until here diff --git a/src/test/ui/unboxed-closures/unboxed-closures-borrow-conflict.nll.stderr b/src/test/ui/unboxed-closures/unboxed-closures-borrow-conflict.nll.stderr new file mode 100644 index 0000000000000..cadda398c6f33 --- /dev/null +++ b/src/test/ui/unboxed-closures/unboxed-closures-borrow-conflict.nll.stderr @@ -0,0 +1,15 @@ +error[E0503]: cannot use `x` because it was mutably borrowed + --> $DIR/unboxed-closures-borrow-conflict.rs:19:14 + | +LL | let f = || x += 1; + | -- - borrow occurs due to use of `x` in closure + | | + | borrow of `x` occurs here +LL | let _y = x; //~ ERROR cannot use `x` because it was mutably borrowed + | ^ use of borrowed `x` +LL | f; + | - borrow later used here + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0503`. diff --git a/src/test/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs b/src/test/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs index 734f89e5e0b8b..aa50fb837733c 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs +++ b/src/test/ui/unboxed-closures/unboxed-closures-borrow-conflict.rs @@ -8,13 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// ignore-compare-mode-nll - // Test that an unboxed closure that mutates a free variable will // cause borrow conflicts. + + fn main() { let mut x = 0; let f = || x += 1; let _y = x; //~ ERROR cannot use `x` because it was mutably borrowed + f; } From 0f009795171c7ea9977110e6aeebe72c67f559c7 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 16 Aug 2018 02:06:26 +0300 Subject: [PATCH 12/18] syntax: process all edition features before other features. --- src/libsyntax/feature_gate.rs | 44 +++++++++++++++++++++++++++-------- src/test/ui/E0705.rs | 2 +- src/test/ui/E0705.stderr | 2 +- 3 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 56e69b9df9e04..74db42ead7d41 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1923,7 +1923,7 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], let mut features = Features::new(); let mut edition_enabled_features = FxHashMap(); - for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() { + for &(name, .., f_edition, set) in ACTIVE_FEATURES { if let Some(f_edition) = f_edition { if f_edition <= crate_edition { set(&mut features, DUMMY_SP); @@ -1932,6 +1932,8 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } } + // Process the edition umbrella feature-gates first, to ensure + // `edition_enabled_features` is completed before it's queried. for attr in krate_attrs { if !attr.check_name("feature") { continue @@ -1939,28 +1941,22 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], let list = match attr.meta_item_list() { Some(list) => list, - None => { - span_err!(span_handler, attr.span, E0555, - "malformed feature attribute, expected #![feature(...)]"); - continue - } + None => continue, }; for mi in list { let name = if let Some(word) = mi.word() { word.name() } else { - span_err!(span_handler, mi.span, E0556, - "malformed feature, expected just one word"); continue }; if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) { if *edition <= crate_edition { - continue + continue; } - for &(name, .., f_edition, set) in ACTIVE_FEATURES.iter() { + for &(name, .., f_edition, set) in ACTIVE_FEATURES { if let Some(f_edition) = f_edition { if f_edition <= *edition { // FIXME(Manishearth) there is currently no way to set @@ -1970,8 +1966,36 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } } } + } + } + } + + for attr in krate_attrs { + if !attr.check_name("feature") { + continue + } + + let list = match attr.meta_item_list() { + Some(list) => list, + None => { + span_err!(span_handler, attr.span, E0555, + "malformed feature attribute, expected #![feature(...)]"); + continue + } + }; + for mi in list { + let name = if let Some(word) = mi.word() { + word.name() + } else { + span_err!(span_handler, mi.span, E0556, + "malformed feature, expected just one word"); continue + }; + + if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) { + // Handled in the separate loop above. + continue; } if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { diff --git a/src/test/ui/E0705.rs b/src/test/ui/E0705.rs index a0ce95e3e02c1..b5fd3cf35f28b 100644 --- a/src/test/ui/E0705.rs +++ b/src/test/ui/E0705.rs @@ -10,9 +10,9 @@ // compile-pass -#![feature(rust_2018_preview)] #![feature(raw_identifiers)] //~^ WARN the feature `raw_identifiers` is included in the Rust 2018 edition +#![feature(rust_2018_preview)] fn main() { let foo = 0; diff --git a/src/test/ui/E0705.stderr b/src/test/ui/E0705.stderr index ebb8dd4975d6f..2aa3077e48c2d 100644 --- a/src/test/ui/E0705.stderr +++ b/src/test/ui/E0705.stderr @@ -1,5 +1,5 @@ warning[E0705]: the feature `raw_identifiers` is included in the Rust 2018 edition - --> $DIR/E0705.rs:14:12 + --> $DIR/E0705.rs:13:12 | LL | #![feature(raw_identifiers)] | ^^^^^^^^^^^^^^^ From 2c4402638e5b24179165110eedd11aca55a0a9e4 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 16 Aug 2018 02:09:12 +0300 Subject: [PATCH 13/18] syntax: also warn about edition "umbrella" features being implied by --edition. --- src/libsyntax/feature_gate.rs | 35 ++++++++++++------- src/test/rustdoc/async-fn.rs | 2 +- src/test/ui/editions/edition-feature-ok.rs | 1 - .../ui/editions/edition-feature-redundant.rs | 17 +++++++++ .../editions/edition-feature-redundant.stderr | 6 ++++ .../extern-crate-idiomatic-in-2018.fixed | 1 - .../extern-crate-idiomatic-in-2018.rs | 1 - .../extern-crate-idiomatic-in-2018.stderr | 6 ++-- 8 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 src/test/ui/editions/edition-feature-redundant.rs create mode 100644 src/test/ui/editions/edition-feature-redundant.stderr diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 74db42ead7d41..dcae9b1e9ca7e 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -1923,6 +1923,14 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], let mut features = Features::new(); let mut edition_enabled_features = FxHashMap(); + for &edition in ALL_EDITIONS { + if edition <= crate_edition { + // The `crate_edition` implies its respective umbrella feature-gate + // (i.e. `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX). + edition_enabled_features.insert(Symbol::intern(edition.feature_name()), edition); + } + } + for &(name, .., f_edition, set) in ACTIVE_FEATURES { if let Some(f_edition) = f_edition { if f_edition <= crate_edition { @@ -1993,25 +2001,26 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], continue }; + if let Some(edition) = edition_enabled_features.get(&name) { + struct_span_warn!( + span_handler, + mi.span, + E0705, + "the feature `{}` is included in the Rust {} edition", + name, + edition, + ).emit(); + continue; + } + if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) { // Handled in the separate loop above. continue; } if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { - if let Some(edition) = edition_enabled_features.get(&name) { - struct_span_warn!( - span_handler, - mi.span, - E0705, - "the feature `{}` is included in the Rust {} edition", - name, - edition, - ).emit(); - } else { - set(&mut features, mi.span); - features.declared_lang_features.push((name, mi.span, None)); - } + set(&mut features, mi.span); + features.declared_lang_features.push((name, mi.span, None)); continue } diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index 21ad5159946fd..f3d39deef1730 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -13,7 +13,7 @@ // FIXME: once `--edition` is stable in rustdoc, remove that `compile-flags` directive -#![feature(rust_2018_preview, async_await, futures_api)] +#![feature(async_await, futures_api)] // @has async_fn/struct.S.html // @has - '//code' 'pub async fn f()' diff --git a/src/test/ui/editions/edition-feature-ok.rs b/src/test/ui/editions/edition-feature-ok.rs index 3a3a6ff95f97e..5896e9a071591 100644 --- a/src/test/ui/editions/edition-feature-ok.rs +++ b/src/test/ui/editions/edition-feature-ok.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags:--edition 2018 // compile-pass #![feature(rust_2018_preview)] diff --git a/src/test/ui/editions/edition-feature-redundant.rs b/src/test/ui/editions/edition-feature-redundant.rs new file mode 100644 index 0000000000000..d20873f5e1163 --- /dev/null +++ b/src/test/ui/editions/edition-feature-redundant.rs @@ -0,0 +1,17 @@ +// 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. + +// edition:2018 +// compile-pass + +#![feature(rust_2018_preview)] +//~^ WARN the feature `rust_2018_preview` is included in the Rust 2018 edition + +fn main() {} diff --git a/src/test/ui/editions/edition-feature-redundant.stderr b/src/test/ui/editions/edition-feature-redundant.stderr new file mode 100644 index 0000000000000..ccf7b21fbc5c0 --- /dev/null +++ b/src/test/ui/editions/edition-feature-redundant.stderr @@ -0,0 +1,6 @@ +warning[E0705]: the feature `rust_2018_preview` is included in the Rust 2018 edition + --> $DIR/edition-feature-redundant.rs:14:12 + | +LL | #![feature(rust_2018_preview)] + | ^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed index 4f99c1240f8f4..c7c73e90988e3 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed @@ -15,7 +15,6 @@ // The "normal case". Ideally we would remove the `extern crate` here, // but we don't. -#![feature(rust_2018_preview)] #![deny(rust_2018_idioms)] #![allow(dead_code)] diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs index 9c1235a296799..ee37a3d766af4 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs @@ -15,7 +15,6 @@ // The "normal case". Ideally we would remove the `extern crate` here, // but we don't. -#![feature(rust_2018_preview)] #![deny(rust_2018_idioms)] #![allow(dead_code)] diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr index b3afa2bd1d592..0ecfd4e4a2ca3 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.stderr @@ -1,18 +1,18 @@ error: unused extern crate - --> $DIR/extern-crate-idiomatic-in-2018.rs:22:1 + --> $DIR/extern-crate-idiomatic-in-2018.rs:21:1 | LL | extern crate edition_lint_paths; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove it | note: lint level defined here - --> $DIR/extern-crate-idiomatic-in-2018.rs:19:9 + --> $DIR/extern-crate-idiomatic-in-2018.rs:18:9 | LL | #![deny(rust_2018_idioms)] | ^^^^^^^^^^^^^^^^ = note: #[deny(unused_extern_crates)] implied by #[deny(rust_2018_idioms)] error: `extern crate` is not idiomatic in the new edition - --> $DIR/extern-crate-idiomatic-in-2018.rs:25:1 + --> $DIR/extern-crate-idiomatic-in-2018.rs:24:1 | LL | extern crate edition_lint_paths as bar; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert it to a `use` From 32e17b5921ea3fbe90cb4b0e3760b03e3f22a143 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 16 Aug 2018 10:36:11 +0300 Subject: [PATCH 14/18] tests: prefer edition: directives to compile-flags:--edition. --- src/test/run-pass/macro-at-most-once-rep.rs | 2 +- .../rust-2018/suggestions-not-always-applicable.fixed | 2 +- .../ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs | 2 +- src/test/ui-fulldeps/unnecessary-extern-crate.rs | 2 +- src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs | 2 +- src/test/ui/borrowck/borrowck-migrate-to-nll.rs | 2 +- .../issue-52967-edition-2018-needs-two-phase-borrows.rs | 2 +- src/test/ui/editions/edition-extern-crate-allowed.rs | 2 +- src/test/ui/in-band-lifetimes/elided-lifetimes.fixed | 2 +- src/test/ui/in-band-lifetimes/elided-lifetimes.rs | 2 +- .../macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs | 2 +- src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep.rs | 2 +- src/test/ui/macros/macro-at-most-once-rep-2015-ques-sep.rs | 2 +- src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs | 2 +- src/test/ui/macros/macro-at-most-once-rep-2018.rs | 2 +- src/test/ui/removing-extern-crate.fixed | 2 +- src/test/ui/removing-extern-crate.rs | 2 +- src/test/ui/rust-2018/async-ident-allowed.rs | 2 +- src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed | 2 +- src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs | 2 +- src/test/ui/rust-2018/issue-52202-use-suggestions.rs | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/test/run-pass/macro-at-most-once-rep.rs b/src/test/run-pass/macro-at-most-once-rep.rs index dcf2222ba6dea..61c3e781c0867 100644 --- a/src/test/run-pass/macro-at-most-once-rep.rs +++ b/src/test/run-pass/macro-at-most-once-rep.rs @@ -18,7 +18,7 @@ // // This test focuses on non-error cases and making sure the correct number of repetitions happen. -// compile-flags: --edition=2018 +// edition:2018 #![feature(macro_at_most_once_rep)] diff --git a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed index e5b47c70863e5..b64ebed030588 100644 --- a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed +++ b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.fixed @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:suggestions-not-always-applicable.rs -// compile-flags: --edition 2015 +// edition:2015 // run-rustfix // rustfix-only-machine-applicable // compile-pass diff --git a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs index e5b47c70863e5..b64ebed030588 100644 --- a/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs +++ b/src/test/ui-fulldeps/rust-2018/suggestions-not-always-applicable.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:suggestions-not-always-applicable.rs -// compile-flags: --edition 2015 +// edition:2015 // run-rustfix // rustfix-only-machine-applicable // compile-pass diff --git a/src/test/ui-fulldeps/unnecessary-extern-crate.rs b/src/test/ui-fulldeps/unnecessary-extern-crate.rs index 0811c79b0a4b9..ea3e0587958b1 100644 --- a/src/test/ui-fulldeps/unnecessary-extern-crate.rs +++ b/src/test/ui-fulldeps/unnecessary-extern-crate.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --edition 2018 +// edition:2018 #![deny(unused_extern_crates)] #![feature(alloc, test, libc)] diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs index 72043938f5351..104c0886311d0 100644 --- a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs +++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs @@ -20,7 +20,7 @@ // revisions: zflag edition // [zflag]compile-flags: -Z borrowck=migrate -// [edition]compile-flags: --edition 2018 +// [edition]edition:2018 #![feature(nll)] diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs index e7f2bfbfedba7..bb6b29072e257 100644 --- a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs +++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs @@ -23,7 +23,7 @@ // revisions: zflag edition //[zflag]compile-flags: -Z borrowck=migrate -//[edition]compile-flags: --edition 2018 +//[edition]edition:2018 //[zflag] run-pass //[edition] run-pass diff --git a/src/test/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs b/src/test/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs index c39fff2644dfd..3b53fb9fc4283 100644 --- a/src/test/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs +++ b/src/test/ui/borrowck/issue-52967-edition-2018-needs-two-phase-borrows.rs @@ -14,7 +14,7 @@ // revisions: ast zflags edition //[zflags]compile-flags: -Z borrowck=migrate -Z two-phase-borrows -//[edition]compile-flags: --edition 2018 +//[edition]edition:2018 // run-pass diff --git a/src/test/ui/editions/edition-extern-crate-allowed.rs b/src/test/ui/editions/edition-extern-crate-allowed.rs index 7368564e250d1..75761a0b5b971 100644 --- a/src/test/ui/editions/edition-extern-crate-allowed.rs +++ b/src/test/ui/editions/edition-extern-crate-allowed.rs @@ -9,7 +9,7 @@ // except according to those terms. // aux-build:edition-extern-crate-allowed.rs -// compile-flags: --edition 2015 +// edition:2015 // compile-pass #![warn(rust_2018_idioms)] diff --git a/src/test/ui/in-band-lifetimes/elided-lifetimes.fixed b/src/test/ui/in-band-lifetimes/elided-lifetimes.fixed index c9381e6350f2b..153e500374688 100644 --- a/src/test/ui/in-band-lifetimes/elided-lifetimes.fixed +++ b/src/test/ui/in-band-lifetimes/elided-lifetimes.fixed @@ -9,7 +9,7 @@ // except according to those terms. // run-rustfix -// compile-flags: --edition 2018 +// edition:2018 #![allow(unused)] #![deny(elided_lifetimes_in_paths)] diff --git a/src/test/ui/in-band-lifetimes/elided-lifetimes.rs b/src/test/ui/in-band-lifetimes/elided-lifetimes.rs index 8151dd01a98d8..41aa7e1a7b7b9 100644 --- a/src/test/ui/in-band-lifetimes/elided-lifetimes.rs +++ b/src/test/ui/in-band-lifetimes/elided-lifetimes.rs @@ -9,7 +9,7 @@ // except according to those terms. // run-rustfix -// compile-flags: --edition 2018 +// edition:2018 #![allow(unused)] #![deny(elided_lifetimes_in_paths)] diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs index fd7925ea3eeeb..63a4ef16a2581 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs +++ b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep-feature-flag.rs @@ -12,7 +12,7 @@ // with the feature flag. // gate-test-macro_at_most_once_rep -// compile-flags: --edition=2015 +// edition:2015 #![feature(macro_at_most_once_rep)] diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep.rs b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep.rs index 90bc19739b872..64848d050cb1e 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep.rs +++ b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-rep.rs @@ -10,7 +10,7 @@ // Test behavior of `?` macro _kleene op_ under the 2015 edition. Namely, it doesn't exist. -// compile-flags: --edition=2015 +// edition:2015 macro_rules! bar { ($(a)?) => {} //~ERROR expected `*` or `+` diff --git a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-sep.rs b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-sep.rs index 2e06b4bd5c240..a7857991079fe 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2015-ques-sep.rs +++ b/src/test/ui/macros/macro-at-most-once-rep-2015-ques-sep.rs @@ -11,7 +11,7 @@ // Test behavior of `?` macro _separator_ under the 2015 edition. Namely, `?` can be used as a // separator, but you get a migration warning for the edition. -// compile-flags: --edition=2015 +// edition:2015 // compile-pass #![warn(rust_2018_compatibility)] diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs index f3107d4f1e4f6..ffabf9bcdf685 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs +++ b/src/test/ui/macros/macro-at-most-once-rep-2018-feature-gate.rs @@ -11,7 +11,7 @@ // Feature gate test for macro_at_most_once_rep under 2018 edition. // gate-test-macro_at_most_once_rep -// compile-flags: --edition=2018 +// edition:2018 macro_rules! foo { ($(a)?) => {} diff --git a/src/test/ui/macros/macro-at-most-once-rep-2018.rs b/src/test/ui/macros/macro-at-most-once-rep-2018.rs index 958a7e0cdf444..5dabe8d952801 100644 --- a/src/test/ui/macros/macro-at-most-once-rep-2018.rs +++ b/src/test/ui/macros/macro-at-most-once-rep-2018.rs @@ -10,7 +10,7 @@ // Tests that `?` is a Kleene op and not a macro separator in the 2018 edition. -// compile-flags: --edition=2018 +// edition:2018 #![feature(macro_at_most_once_rep)] diff --git a/src/test/ui/removing-extern-crate.fixed b/src/test/ui/removing-extern-crate.fixed index 83b35cec80956..90427b061b652 100644 --- a/src/test/ui/removing-extern-crate.fixed +++ b/src/test/ui/removing-extern-crate.fixed @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --edition 2018 +// edition:2018 // aux-build:removing-extern-crate.rs // run-rustfix // compile-pass diff --git a/src/test/ui/removing-extern-crate.rs b/src/test/ui/removing-extern-crate.rs index 29479086460e6..3905d285becb5 100644 --- a/src/test/ui/removing-extern-crate.rs +++ b/src/test/ui/removing-extern-crate.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --edition 2018 +// edition:2018 // aux-build:removing-extern-crate.rs // run-rustfix // compile-pass diff --git a/src/test/ui/rust-2018/async-ident-allowed.rs b/src/test/ui/rust-2018/async-ident-allowed.rs index fd4eae1f9b54c..3bc468483bda2 100644 --- a/src/test/ui/rust-2018/async-ident-allowed.rs +++ b/src/test/ui/rust-2018/async-ident-allowed.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --edition 2015 +// edition:2015 #![deny(rust_2018_compatibility)] diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed index c7c73e90988e3..fc81ab08f624d 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.fixed @@ -10,7 +10,7 @@ // aux-build:edition-lint-paths.rs // run-rustfix -// compile-flags:--edition 2018 +// edition:2018 // The "normal case". Ideally we would remove the `extern crate` here, // but we don't. diff --git a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs index ee37a3d766af4..72751f2080cc9 100644 --- a/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs +++ b/src/test/ui/rust-2018/extern-crate-idiomatic-in-2018.rs @@ -10,7 +10,7 @@ // aux-build:edition-lint-paths.rs // run-rustfix -// compile-flags:--edition 2018 +// edition:2018 // The "normal case". Ideally we would remove the `extern crate` here, // but we don't. diff --git a/src/test/ui/rust-2018/issue-52202-use-suggestions.rs b/src/test/ui/rust-2018/issue-52202-use-suggestions.rs index 5acd19c2471e6..deb80411bbf64 100644 --- a/src/test/ui/rust-2018/issue-52202-use-suggestions.rs +++ b/src/test/ui/rust-2018/issue-52202-use-suggestions.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -// compile-flags: --edition 2018 +// edition:2018 // The local `use` suggestion should start with `crate::` (but the // standard-library suggestions should not, obviously). From ed39cc074aa5d25ec8d7fc2e17b69bf97c148cda Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 16 Aug 2018 10:17:06 -0700 Subject: [PATCH 15/18] wasm: Remove --strip-debug argument to LLD Originally added in #52887 this commit disables passing `--strip-debug` to LLD when optimized. This bring back the original bug of emitting broken debuginfo but currently it *also* strips the `name` section which makes it very difficult to inspect the final binary. A real fix is happening at https://reviews.llvm.org/D50729 and we can reevaluate once we've updated LLD to have that commit. --- src/librustc_codegen_llvm/back/linker.rs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/librustc_codegen_llvm/back/linker.rs b/src/librustc_codegen_llvm/back/linker.rs index ef98fae9cc7ee..6311ab7c74c1c 100644 --- a/src/librustc_codegen_llvm/back/linker.rs +++ b/src/librustc_codegen_llvm/back/linker.rs @@ -1006,18 +1006,6 @@ impl<'a> Linker for WasmLd<'a> { OptLevel::Size => "-O2", OptLevel::SizeMin => "-O2" }); - match self.sess.opts.optimize { - OptLevel::No => (), - OptLevel::Less | - OptLevel::Default | - OptLevel::Aggressive | - OptLevel::Size | - OptLevel::SizeMin => { - // LLD generates incorrect debugging information when - // optimization is applied: strip debug sections. - self.cmd.arg("--strip-debug"); - } - } } fn pgo_gen(&mut self) { From 742ef5864a437a86600dc2d93461d781240ede7c Mon Sep 17 00:00:00 2001 From: Corey Farwell Date: Mon, 30 Jul 2018 09:07:51 -0400 Subject: [PATCH 16/18] Implement Iterator::size_hint for Elaborator. --- src/librustc/traits/util.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 875c7199f6d11..40f13ac06f56f 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -239,6 +239,10 @@ impl<'cx, 'gcx, 'tcx> Elaborator<'cx, 'gcx, 'tcx> { impl<'cx, 'gcx, 'tcx> Iterator for Elaborator<'cx, 'gcx, 'tcx> { type Item = ty::Predicate<'tcx>; + fn size_hint(&self) -> (usize, Option) { + (self.stack.len(), None) + } + fn next(&mut self) -> Option> { // Extract next item from top-most stack frame, if any. let next_predicate = match self.stack.pop() { From 9b1d3c70ac5e16fd43daf0b56c739c6bd5ded3fd Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 14 Aug 2018 12:54:43 +0300 Subject: [PATCH 17/18] rustc_resolve: don't allow paths starting with `::crate`. --- src/Cargo.lock | 8 +- .../src/language-features/crate-in-paths.md | 9 +-- .../extern-absolute-paths.md | 2 +- src/librustc/Cargo.toml | 2 +- src/librustc_resolve/lib.rs | 79 +++++++++---------- src/librustc_traits/Cargo.toml | 2 +- .../crate-path-absolute.rs | 4 +- .../crate-path-visibility-ambiguity.rs | 3 +- .../feature-gate-crate_in_paths.rs | 2 +- .../feature-gate-crate_in_paths.stderr | 6 +- .../crate-path-non-absolute.rs | 1 + .../crate-path-non-absolute.stderr | 12 ++- .../keyword-crate-as-identifier.rs | 3 +- .../keyword-crate-as-identifier.stderr | 8 +- .../ui/rust-2018/edition-lint-paths.fixed | 2 +- src/test/ui/rust-2018/edition-lint-paths.rs | 2 +- 16 files changed, 71 insertions(+), 74 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 99b768ab1a92e..4e16e61aa0d39 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -308,7 +308,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chalk-engine" -version = "0.6.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1897,7 +1897,7 @@ dependencies = [ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", @@ -2408,7 +2408,7 @@ name = "rustc_traits" version = "0.0.0" dependencies = [ "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -3135,7 +3135,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1" "checksum cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "2119ea4867bd2b8ed3aecab467709720b2d55b1bcfe09f772fd68066eaf15275" "checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e" -"checksum chalk-engine 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a146c19172c7eea48ea55a7123ac95da786639bc665097f1e14034ee5f1d8699" +"checksum chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25ce2f28f55ed544a2a3756b7acf41dd7d6f27acffb2086439950925506af7d0" "checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e" "checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" diff --git a/src/doc/unstable-book/src/language-features/crate-in-paths.md b/src/doc/unstable-book/src/language-features/crate-in-paths.md index f1656993e87a5..9901dc1ebe307 100644 --- a/src/doc/unstable-book/src/language-features/crate-in-paths.md +++ b/src/doc/unstable-book/src/language-features/crate-in-paths.md @@ -9,10 +9,6 @@ The tracking issue for this feature is: [#44660] The `crate_in_paths` feature allows to explicitly refer to the crate root in absolute paths using keyword `crate`. -`crate` can be used *only* in absolute paths, i.e. either in `::crate::a::b::c` form or in `use` -items where the starting `::` is added implicitly. -Paths like `crate::a::b::c` are not accepted currently. - This feature is required in `feature(extern_absolute_paths)` mode to refer to any absolute path in the local crate (absolute paths refer to extern crates by default in that mode), but can be used without `feature(extern_absolute_paths)` as well. @@ -39,15 +35,14 @@ mod n use crate as root; pub fn check() { assert_eq!(f(), 1); - // `::` is required in non-import paths - assert_eq!(::crate::m::g(), 2); + assert_eq!(crate::m::g(), 2); assert_eq!(root::m::h(), 3); } } fn main() { assert_eq!(f(), 1); - assert_eq!(::crate::m::g(), 2); + assert_eq!(crate::m::g(), 2); assert_eq!(root::m::h(), 3); n::check(); } diff --git a/src/doc/unstable-book/src/language-features/extern-absolute-paths.md b/src/doc/unstable-book/src/language-features/extern-absolute-paths.md index f45c5053e8dbc..6a22e7eba646b 100644 --- a/src/doc/unstable-book/src/language-features/extern-absolute-paths.md +++ b/src/doc/unstable-book/src/language-features/extern-absolute-paths.md @@ -12,7 +12,7 @@ The `extern_absolute_paths` feature enables mode allowing to refer to names from `::my_crate::a::b` will resolve to path `a::b` in crate `my_crate`. `feature(crate_in_paths)` can be used in `feature(extern_absolute_paths)` mode for referring -to absolute paths in the local crate (`::crate::a::b`). +to absolute paths in the local crate (`crate::a::b`). `feature(extern_in_paths)` provides the same effect by using keyword `extern` to refer to paths from other crates (`extern::my_crate::a::b`). diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 088b9436d0fc9..59b5b58e61eac 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -31,7 +31,7 @@ syntax_pos = { path = "../libsyntax_pos" } backtrace = "0.3.3" parking_lot = "0.5.5" byteorder = { version = "1.1", features = ["i128"]} -chalk-engine = { version = "0.6.0", default-features=false } +chalk-engine = { version = "0.7.0", default-features=false } rustc_fs_util = { path = "../librustc_fs_util" } # Note that these dependencies are a lie, they're just here to get linkage to diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 992ea12ffa2b1..729689e35c998 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3459,33 +3459,37 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS }; let name = ident.name; - if i == 0 && ns == TypeNS && name == keywords::SelfValue.name() { - let mut ctxt = ident.span.ctxt().modern(); - module = Some(ModuleOrUniformRoot::Module( - self.resolve_self(&mut ctxt, self.current_module))); - continue - } else if allow_super && ns == TypeNS && name == keywords::Super.name() { - let mut ctxt = ident.span.ctxt().modern(); - let self_module_parent = match i { - 0 => self.resolve_self(&mut ctxt, self.current_module).parent, - _ => match module { - Some(ModuleOrUniformRoot::Module(module)) => module.parent, - _ => None, - }, - }; - if let Some(parent) = self_module_parent { - module = Some(ModuleOrUniformRoot::Module( - self.resolve_self(&mut ctxt, parent))); - continue - } else { + allow_super &= ns == TypeNS && + (name == keywords::SelfValue.name() || + name == keywords::Super.name()); + + if ns == TypeNS { + if allow_super && name == keywords::Super.name() { + let mut ctxt = ident.span.ctxt().modern(); + let self_module = match i { + 0 => Some(self.resolve_self(&mut ctxt, self.current_module)), + _ => match module { + Some(ModuleOrUniformRoot::Module(module)) => Some(module), + _ => None, + }, + }; + if let Some(self_module) = self_module { + if let Some(parent) = self_module.parent { + module = Some(ModuleOrUniformRoot::Module( + self.resolve_self(&mut ctxt, parent))); + continue; + } + } let msg = "There are too many initial `super`s.".to_string(); return PathResult::Failed(ident.span, msg, false); } - } - allow_super = false; - - if ns == TypeNS { if i == 0 { + if name == keywords::SelfValue.name() { + let mut ctxt = ident.span.ctxt().modern(); + module = Some(ModuleOrUniformRoot::Module( + self.resolve_self(&mut ctxt, self.current_module))); + continue; + } if name == keywords::Extern.name() || name == keywords::CrateRoot.name() && self.session.features_untracked().extern_absolute_paths && @@ -3493,30 +3497,19 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { module = Some(ModuleOrUniformRoot::UniformRoot(name)); continue; } - } - if (i == 0 && name == keywords::CrateRoot.name()) || - (i == 0 && name == keywords::Crate.name()) || - (i == 0 && name == keywords::DollarCrate.name()) || - (i == 1 && name == keywords::Crate.name() && - path[0].name == keywords::CrateRoot.name()) { - // `::a::b`, `crate::a::b`, `::crate::a::b` or `$crate::a::b` - module = Some(ModuleOrUniformRoot::Module( - self.resolve_crate_root(ident))); - continue + if name == keywords::CrateRoot.name() || + name == keywords::Crate.name() || + name == keywords::DollarCrate.name() { + // `::a::b`, `crate::a::b` or `$crate::a::b` + module = Some(ModuleOrUniformRoot::Module( + self.resolve_crate_root(ident))); + continue; + } } } // Report special messages for path segment keywords in wrong positions. - if name == keywords::CrateRoot.name() && i != 0 || - name == keywords::DollarCrate.name() && i != 0 || - name == keywords::SelfValue.name() && i != 0 || - name == keywords::SelfType.name() && i != 0 || - name == keywords::Super.name() && i != 0 || - name == keywords::Extern.name() && i != 0 || - // we allow crate::foo and ::crate::foo but nothing else - name == keywords::Crate.name() && i > 1 && - path[0].name != keywords::CrateRoot.name() || - name == keywords::Crate.name() && path.len() == 1 { + if ident.is_path_segment_keyword() && i != 0 { let name_str = if name == keywords::CrateRoot.name() { "crate root".to_string() } else { diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index 134983911100e..3e1a6ca9aff7c 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -16,4 +16,4 @@ rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -chalk-engine = { version = "0.6.0", default-features=false } +chalk-engine = { version = "0.7.0", default-features=false } diff --git a/src/test/run-pass/rfc-2126-crate-paths/crate-path-absolute.rs b/src/test/run-pass/rfc-2126-crate-paths/crate-path-absolute.rs index 7003541e86cd3..31f683a173550 100644 --- a/src/test/run-pass/rfc-2126-crate-paths/crate-path-absolute.rs +++ b/src/test/run-pass/rfc-2126-crate-paths/crate-path-absolute.rs @@ -28,14 +28,14 @@ mod n use crate as root; pub fn check() { assert_eq!(f(), 1); - assert_eq!(::crate::m::g(), 2); + assert_eq!(crate::m::g(), 2); assert_eq!(root::m::h(), 3); } } fn main() { assert_eq!(f(), 1); - assert_eq!(::crate::m::g(), 2); + assert_eq!(crate::m::g(), 2); assert_eq!(root::m::h(), 3); n::check(); } diff --git a/src/test/run-pass/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs b/src/test/run-pass/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs index 1a8d2d80ef4d9..4646d81cf518f 100644 --- a/src/test/run-pass/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs +++ b/src/test/run-pass/rfc-2126-crate-paths/crate-path-visibility-ambiguity.rs @@ -14,8 +14,9 @@ mod m { pub struct Z; pub struct S1(crate (::m::Z)); // OK - pub struct S2(::crate ::m::Z); // OK + pub struct S2((crate ::m::Z)); // OK pub struct S3(crate ::m::Z); // OK + pub struct S4(crate crate::m::Z); // OK } fn main() { diff --git a/src/test/ui/feature-gates/feature-gate-crate_in_paths.rs b/src/test/ui/feature-gates/feature-gate-crate_in_paths.rs index 830ec5959b702..e667dab621bda 100644 --- a/src/test/ui/feature-gates/feature-gate-crate_in_paths.rs +++ b/src/test/ui/feature-gates/feature-gate-crate_in_paths.rs @@ -11,5 +11,5 @@ struct S; fn main() { - let _ = ::crate::S; //~ ERROR `crate` in paths is experimental + let _ = crate::S; //~ ERROR `crate` in paths is experimental } diff --git a/src/test/ui/feature-gates/feature-gate-crate_in_paths.stderr b/src/test/ui/feature-gates/feature-gate-crate_in_paths.stderr index 1d0eed5319874..32115ba2111b5 100644 --- a/src/test/ui/feature-gates/feature-gate-crate_in_paths.stderr +++ b/src/test/ui/feature-gates/feature-gate-crate_in_paths.stderr @@ -1,8 +1,8 @@ error[E0658]: `crate` in paths is experimental (see issue #45477) - --> $DIR/feature-gate-crate_in_paths.rs:14:15 + --> $DIR/feature-gate-crate_in_paths.rs:14:13 | -LL | let _ = ::crate::S; //~ ERROR `crate` in paths is experimental - | ^^^^^ +LL | let _ = crate::S; //~ ERROR `crate` in paths is experimental + | ^^^^^ | = help: add #![feature(crate_in_paths)] to the crate attributes to enable diff --git a/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs b/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs index 65f11c063ed2e..a44ca9d2d25c9 100644 --- a/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs +++ b/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.rs @@ -15,6 +15,7 @@ struct S; pub mod m { fn f() { let s = ::m::crate::S; //~ ERROR failed to resolve + let s1 = ::crate::S; //~ ERROR failed to resolve let s2 = crate::S; // no error } } diff --git a/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr b/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr index f4d33e0b9db2f..f16c849607766 100644 --- a/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr +++ b/src/test/ui/rfc-2126-crate-paths/crate-path-non-absolute.stderr @@ -1,9 +1,15 @@ -error[E0433]: failed to resolve. Could not find `crate` in `m` +error[E0433]: failed to resolve. `crate` in paths can only be used in start position --> $DIR/crate-path-non-absolute.rs:17:22 | LL | let s = ::m::crate::S; //~ ERROR failed to resolve - | ^^^^^ Could not find `crate` in `m` + | ^^^^^ `crate` in paths can only be used in start position -error: aborting due to previous error +error[E0433]: failed to resolve. global paths cannot start with `crate` + --> $DIR/crate-path-non-absolute.rs:18:20 + | +LL | let s1 = ::crate::S; //~ ERROR failed to resolve + | ^^^^^ global paths cannot start with `crate` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0433`. diff --git a/src/test/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs b/src/test/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs index bdd03be4356c9..3ebb3a25d8d35 100644 --- a/src/test/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs +++ b/src/test/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.rs @@ -11,5 +11,6 @@ #![feature(crate_in_paths)] fn main() { - let crate = 0; //~ ERROR failed to resolve. `crate` in paths can only be used in start position + let crate = 0; + //~^ ERROR expected unit struct/variant or constant, found module `crate` } diff --git a/src/test/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.stderr b/src/test/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.stderr index e4d2db057f272..ec44fb4db0090 100644 --- a/src/test/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.stderr +++ b/src/test/ui/rfc-2126-crate-paths/keyword-crate-as-identifier.stderr @@ -1,9 +1,9 @@ -error[E0433]: failed to resolve. `crate` in paths can only be used in start position +error[E0532]: expected unit struct/variant or constant, found module `crate` --> $DIR/keyword-crate-as-identifier.rs:14:9 | -LL | let crate = 0; //~ ERROR failed to resolve. `crate` in paths can only be used in start position - | ^^^^^ `crate` in paths can only be used in start position +LL | let crate = 0; + | ^^^^^ not a unit struct/variant or constant error: aborting due to previous error -For more information about this error, try `rustc --explain E0433`. +For more information about this error, try `rustc --explain E0532`. diff --git a/src/test/ui/rust-2018/edition-lint-paths.fixed b/src/test/ui/rust-2018/edition-lint-paths.fixed index ecc7190933409..8a2b9c1f27213 100644 --- a/src/test/ui/rust-2018/edition-lint-paths.fixed +++ b/src/test/ui/rust-2018/edition-lint-paths.fixed @@ -68,7 +68,7 @@ fn main() { //~^ ERROR absolute //~| WARN this was previously accepted let x = bar::Bar; - let x = ::crate::bar::Bar; + let x = crate::bar::Bar; let x = self::bar::Bar; foo::test(); diff --git a/src/test/ui/rust-2018/edition-lint-paths.rs b/src/test/ui/rust-2018/edition-lint-paths.rs index c08be85531d5e..b6e5d5a8afbf1 100644 --- a/src/test/ui/rust-2018/edition-lint-paths.rs +++ b/src/test/ui/rust-2018/edition-lint-paths.rs @@ -68,7 +68,7 @@ fn main() { //~^ ERROR absolute //~| WARN this was previously accepted let x = bar::Bar; - let x = ::crate::bar::Bar; + let x = crate::bar::Bar; let x = self::bar::Bar; foo::test(); From f5556a6a28683e3dd0f039948964a5361a70a498 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 17 Aug 2018 14:01:57 +0200 Subject: [PATCH 18/18] Gratuitous at byte boundaries in hex i32 literals in some doc-tests --- src/libcore/num/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs index feaedf4b90912..37856dc546935 100644 --- a/src/libcore/num/mod.rs +++ b/src/libcore/num/mod.rs @@ -1891,7 +1891,7 @@ $EndFeature, " /// ``` /// #![feature(int_to_from_bytes)] /// - /// let bytes = 0x12345678i32.to_be_bytes(); + /// let bytes = 0x12_34_56_78_i32.to_be_bytes(); /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); /// ``` #[unstable(feature = "int_to_from_bytes", issue = "52963")] @@ -1908,7 +1908,7 @@ $EndFeature, " /// ``` /// #![feature(int_to_from_bytes)] /// - /// let bytes = 0x12345678i32.to_le_bytes(); + /// let bytes = 0x12_34_56_78_i32.to_le_bytes(); /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]); /// ``` #[unstable(feature = "int_to_from_bytes", issue = "52963")] @@ -3576,7 +3576,7 @@ $EndFeature, " /// ``` /// #![feature(int_to_from_bytes)] /// - /// let bytes = 0x12345678i32.to_be_bytes(); + /// let bytes = 0x12_34_56_78_i32.to_be_bytes(); /// assert_eq!(bytes, [0x12, 0x34, 0x56, 0x78]); /// ``` #[unstable(feature = "int_to_from_bytes", issue = "52963")] @@ -3593,7 +3593,7 @@ $EndFeature, " /// ``` /// #![feature(int_to_from_bytes)] /// - /// let bytes = 0x12345678i32.to_le_bytes(); + /// let bytes = 0x12_34_56_78_i32.to_le_bytes(); /// assert_eq!(bytes, [0x78, 0x56, 0x34, 0x12]); /// ``` #[unstable(feature = "int_to_from_bytes", issue = "52963")]