From 16e10bf81ee73f61cf813acef3d5dbbce4f66da2 Mon Sep 17 00:00:00 2001 From: Francesca Lovebloom Date: Wed, 7 Oct 2020 15:46:05 -0700 Subject: [PATCH 01/13] Revert "Allow dynamic linking for iOS/tvOS targets." This reverts commit 56e115a2627ba8bdd2e66c759457af96b2b0286a. --- compiler/rustc_target/src/spec/apple_sdk_base.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs index e34277d5af04c..1b17c2c278f9a 100644 --- a/compiler/rustc_target/src/spec/apple_sdk_base.rs +++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs @@ -34,6 +34,7 @@ fn link_env_remove(arch: Arch) -> Vec { pub fn opts(arch: Arch) -> TargetOptions { TargetOptions { cpu: target_cpu(arch), + dynamic_linking: false, executables: true, link_env_remove: link_env_remove(arch), has_elf_tls: false, From a9470d0522368f67d8aaa551318e3feb2d18e790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 21 Oct 2020 00:00:00 +0000 Subject: [PATCH 02/13] Simplify assert terminator only if condition evaluates to expected value --- compiler/rustc_mir/src/transform/simplify_branches.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir/src/transform/simplify_branches.rs b/compiler/rustc_mir/src/transform/simplify_branches.rs index 5f63c03993d3a..a9a45e61a38cb 100644 --- a/compiler/rustc_mir/src/transform/simplify_branches.rs +++ b/compiler/rustc_mir/src/transform/simplify_branches.rs @@ -49,9 +49,10 @@ impl<'tcx> MirPass<'tcx> for SimplifyBranches { } TerminatorKind::Assert { target, cond: Operand::Constant(ref c), expected, .. - } if (c.literal.try_eval_bool(tcx, param_env) == Some(true)) == expected => { - TerminatorKind::Goto { target } - } + } => match c.literal.try_eval_bool(tcx, param_env) { + Some(v) if v == expected => TerminatorKind::Goto { target }, + _ => continue, + }, TerminatorKind::FalseEdge { real_target, .. } => { TerminatorKind::Goto { target: real_target } } From 40ab18d97dab9df68418d19ef8a40c3218142d5f Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Thu, 22 Oct 2020 23:07:48 +0200 Subject: [PATCH 03/13] improve const infer error --- compiler/rustc_middle/src/infer/unify_key.rs | 16 +++++----------- .../ui/const-generics/infer/issue-77092.stderr | 2 +- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index 4d884dde39387..cf5e99845d189 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -176,17 +176,17 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> { type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>); fn unify_values(value1: &Self, value2: &Self) -> Result { - let (val, span) = match (value1.val, value2.val) { + let (val, origin) = match (value1.val, value2.val) { (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => { bug!("equating two const variables, both of which have known values") } // If one side is known, prefer that one. (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => { - (value1.val, value1.origin.span) + (value1.val, value1.origin) } (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => { - (value2.val, value2.origin.span) + (value2.val, value2.origin) } // If both sides are *unknown*, it hardly matters, does it? @@ -200,17 +200,11 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> { // universe is the minimum of the two universes, because that is // the one which contains the fewest names in scope. let universe = cmp::min(universe1, universe2); - (ConstVariableValue::Unknown { universe }, value1.origin.span) + (ConstVariableValue::Unknown { universe }, value1.origin) } }; - Ok(ConstVarValue { - origin: ConstVariableOrigin { - kind: ConstVariableOriginKind::ConstInference, - span: span, - }, - val, - }) + Ok(ConstVarValue { origin, val }) } } diff --git a/src/test/ui/const-generics/infer/issue-77092.stderr b/src/test/ui/const-generics/infer/issue-77092.stderr index e84ff8baeea53..63facbf3b8c0f 100644 --- a/src/test/ui/const-generics/infer/issue-77092.stderr +++ b/src/test/ui/const-generics/infer/issue-77092.stderr @@ -2,7 +2,7 @@ error[E0282]: type annotations needed --> $DIR/issue-77092.rs:13:26 | LL | println!("{:?}", take_array_from_mut(&mut arr, i)); - | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of the constant `{_: usize}` + | ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `take_array_from_mut` error: aborting due to previous error From 09135e4e758c6fb5a3ca91924a78521f749acda9 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 23 Oct 2020 16:09:17 +0900 Subject: [PATCH 04/13] Add regression test for issue-77475 --- src/test/ui/macros/issue-77475.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/test/ui/macros/issue-77475.rs diff --git a/src/test/ui/macros/issue-77475.rs b/src/test/ui/macros/issue-77475.rs new file mode 100644 index 0000000000000..7b32a33ea4f17 --- /dev/null +++ b/src/test/ui/macros/issue-77475.rs @@ -0,0 +1,10 @@ +// check-pass +// Regression test of #77475, this used to be ICE. + +#![feature(decl_macro)] + +use crate as _; + +pub macro ice(){} + +fn main() {} From e1c524cd457bd02435a47214052320f8d4bfa999 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Fri, 23 Oct 2020 09:33:47 +0200 Subject: [PATCH 05/13] review --- compiler/rustc_middle/src/infer/unify_key.rs | 21 +++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs index cf5e99845d189..16e9aafb25a54 100644 --- a/compiler/rustc_middle/src/infer/unify_key.rs +++ b/compiler/rustc_middle/src/infer/unify_key.rs @@ -175,19 +175,15 @@ impl<'tcx> UnifyKey for ty::ConstVid<'tcx> { impl<'tcx> UnifyValue for ConstVarValue<'tcx> { type Error = (&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>); - fn unify_values(value1: &Self, value2: &Self) -> Result { - let (val, origin) = match (value1.val, value2.val) { + fn unify_values(&value1: &Self, &value2: &Self) -> Result { + Ok(match (value1.val, value2.val) { (ConstVariableValue::Known { .. }, ConstVariableValue::Known { .. }) => { bug!("equating two const variables, both of which have known values") } // If one side is known, prefer that one. - (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => { - (value1.val, value1.origin) - } - (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => { - (value2.val, value2.origin) - } + (ConstVariableValue::Known { .. }, ConstVariableValue::Unknown { .. }) => value1, + (ConstVariableValue::Unknown { .. }, ConstVariableValue::Known { .. }) => value2, // If both sides are *unknown*, it hardly matters, does it? ( @@ -200,11 +196,12 @@ impl<'tcx> UnifyValue for ConstVarValue<'tcx> { // universe is the minimum of the two universes, because that is // the one which contains the fewest names in scope. let universe = cmp::min(universe1, universe2); - (ConstVariableValue::Unknown { universe }, value1.origin) + ConstVarValue { + val: ConstVariableValue::Unknown { universe }, + origin: value1.origin, + } } - }; - - Ok(ConstVarValue { origin, val }) + }) } } From 9b90e1762e6cb21baa504a27530b9aa404fbe3ac Mon Sep 17 00:00:00 2001 From: Canop Date: Thu, 1 Oct 2020 11:13:38 +0200 Subject: [PATCH 06/13] add `insert` and `insert_with` to `Option` This removes a cause of `unwrap` and code complexity. This allows replacing ``` option_value = Some(build()); option_value.as_mut().unwrap() ``` with ``` option_value.insert(build()) ``` or ``` option_value.insert_with(build) ``` It's also useful in contexts not requiring the mutability of the reference. Here's a typical cache example: ``` let checked_cache = cache.as_ref().filter(|e| e.is_valid()); let content = match checked_cache { Some(e) => &e.content, None => { cache = Some(compute_cache_entry()); // unwrap is OK because we just filled the option &cache.as_ref().unwrap().content } }; ``` It can be changed into ``` let checked_cache = cache.as_ref().filter(|e| e.is_valid()); let content = match checked_cache { Some(e) => &e.content, None => &cache.insert_with(compute_cache_entry).content, }; ``` --- library/core/src/option.rs | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 825144e5a6fbe..394be746ec2fa 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -562,6 +562,52 @@ impl Option { } } + ///////////////////////////////////////////////////////////////////////// + // Setting a new value + ///////////////////////////////////////////////////////////////////////// + + /// Inserts `v` into the option then returns a mutable reference + /// to the contained value. + /// + /// # Example + /// + /// ``` + /// #![feature(option_insert)] + /// + /// let mut o = None; + /// let v = o.insert(3); + /// assert_eq!(*v, 3); + /// ``` + #[inline] + #[unstable(feature = "option_insert", reason = "new API", issue = "none")] + pub fn insert(&mut self, v: T) -> &mut T { + self.insert_with(|| v) + } + + /// Inserts a value computed from `f` into the option, then returns a + /// mutable reference to the contained value. + /// + /// # Example + /// + /// ``` + /// #![feature(option_insert)] + /// + /// let mut o = None; + /// let v = o.insert_with(|| 3); + /// assert_eq!(*v, 3); + /// ``` + #[inline] + #[unstable(feature = "option_insert", reason = "new API", issue = "none")] + pub fn insert_with T>(&mut self, f: F) -> &mut T { + *self = Some(f()); + + match *self { + Some(ref mut v) => v, + // SAFETY: the code above just filled the option + None => unsafe { hint::unreachable_unchecked() }, + } + } + ///////////////////////////////////////////////////////////////////////// // Iterator constructors ///////////////////////////////////////////////////////////////////////// From e8df2a426959fa3ff4f65eae85e618394bf27e28 Mon Sep 17 00:00:00 2001 From: Canop Date: Thu, 1 Oct 2020 13:24:33 +0200 Subject: [PATCH 07/13] remove `option.insert_with` `option.insert` covers both needs anyway, `insert_with` is redundant. --- library/core/src/option.rs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 394be746ec2fa..64541da300e86 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -581,25 +581,7 @@ impl Option { #[inline] #[unstable(feature = "option_insert", reason = "new API", issue = "none")] pub fn insert(&mut self, v: T) -> &mut T { - self.insert_with(|| v) - } - - /// Inserts a value computed from `f` into the option, then returns a - /// mutable reference to the contained value. - /// - /// # Example - /// - /// ``` - /// #![feature(option_insert)] - /// - /// let mut o = None; - /// let v = o.insert_with(|| 3); - /// assert_eq!(*v, 3); - /// ``` - #[inline] - #[unstable(feature = "option_insert", reason = "new API", issue = "none")] - pub fn insert_with T>(&mut self, f: F) -> &mut T { - *self = Some(f()); + *self = Some(v); match *self { Some(ref mut v) => v, From 60a96cae336b621be3a5e01cf6c87649b327f836 Mon Sep 17 00:00:00 2001 From: Canop Date: Thu, 1 Oct 2020 16:05:01 +0200 Subject: [PATCH 08/13] more tests in option.insert, code cleaning in option Code cleaning made according to suggestions in discussion on PR ##77392 impacts insert, get_or_insert and get_or_insert_with. --- library/core/src/option.rs | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 64541da300e86..65575f4c41bad 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -574,17 +574,22 @@ impl Option { /// ``` /// #![feature(option_insert)] /// - /// let mut o = None; - /// let v = o.insert(3); - /// assert_eq!(*v, 3); + /// let mut opt = None; + /// let val = opt.insert(1); + /// assert_eq!(*val, 1); + /// assert_eq!(opt.unwrap(), 1); + /// let val = opt.insert(2); + /// assert_eq!(*val, 2); + /// *val = 3; + /// assert_eq!(opt.unwrap(), 3); /// ``` #[inline] - #[unstable(feature = "option_insert", reason = "new API", issue = "none")] - pub fn insert(&mut self, v: T) -> &mut T { - *self = Some(v); + #[unstable(feature = "option_insert", reason = "newly added", issue = "none")] + pub fn insert(&mut self, val: T) -> &mut T { + *self = Some(val); - match *self { - Some(ref mut v) => v, + match self { + Some(v) => v, // SAFETY: the code above just filled the option None => unsafe { hint::unreachable_unchecked() }, } @@ -839,8 +844,8 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - pub fn get_or_insert(&mut self, v: T) -> &mut T { - self.get_or_insert_with(|| v) + pub fn get_or_insert(&mut self, val: T) -> &mut T { + self.get_or_insert_with(|| val) } /// Inserts a value computed from `f` into the option if it is [`None`], then @@ -867,8 +872,8 @@ impl Option { *self = Some(f()); } - match *self { - Some(ref mut v) => v, + match self { + Some(v) => v, // SAFETY: a `None` variant for `self` would have been replaced by a `Some` // variant in the code above. None => unsafe { hint::unreachable_unchecked() }, From cc8b77a7cf0e1179b148a70c8f760a7ba3c1debd Mon Sep 17 00:00:00 2001 From: Canop Date: Sat, 3 Oct 2020 10:29:11 +0200 Subject: [PATCH 09/13] fix naming unconsistency between function doc and prototype --- library/core/src/option.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 65575f4c41bad..8fd3bfe77b800 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -566,8 +566,7 @@ impl Option { // Setting a new value ///////////////////////////////////////////////////////////////////////// - /// Inserts `v` into the option then returns a mutable reference - /// to the contained value. + /// Inserts `value` into the option then returns a mutable reference to it. /// /// # Example /// @@ -585,8 +584,8 @@ impl Option { /// ``` #[inline] #[unstable(feature = "option_insert", reason = "newly added", issue = "none")] - pub fn insert(&mut self, val: T) -> &mut T { - *self = Some(val); + pub fn insert(&mut self, value: T) -> &mut T { + *self = Some(value); match self { Some(v) => v, @@ -825,7 +824,7 @@ impl Option { // Entry-like operations to insert if None and return a reference ///////////////////////////////////////////////////////////////////////// - /// Inserts `v` into the option if it is [`None`], then + /// Inserts `value` into the option if it is [`None`], then /// returns a mutable reference to the contained value. /// /// # Examples @@ -844,12 +843,12 @@ impl Option { /// ``` #[inline] #[stable(feature = "option_entry", since = "1.20.0")] - pub fn get_or_insert(&mut self, val: T) -> &mut T { - self.get_or_insert_with(|| val) + pub fn get_or_insert(&mut self, value: T) -> &mut T { + self.get_or_insert_with(|| value) } - /// Inserts a value computed from `f` into the option if it is [`None`], then - /// returns a mutable reference to the contained value. + /// Inserts a value computed from `f` into the option if it is [`None`], + /// then returns a mutable reference to the contained value. /// /// # Examples /// From 39557799c763d75b58cbd7235af49a29c4d1212c Mon Sep 17 00:00:00 2001 From: Canop Date: Fri, 23 Oct 2020 11:08:09 +0200 Subject: [PATCH 10/13] Update library/core/src/option.rs Co-authored-by: Mara Bos --- library/core/src/option.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 8fd3bfe77b800..4e8a74d9162a5 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -568,6 +568,8 @@ impl Option { /// Inserts `value` into the option then returns a mutable reference to it. /// + /// If the option already contains a value, the old value is dropped. + /// /// # Example /// /// ``` From 415a8e526d0e99f0e85e3b06bad9d2f2867910c5 Mon Sep 17 00:00:00 2001 From: Canop Date: Fri, 23 Oct 2020 11:09:15 +0200 Subject: [PATCH 11/13] Update library/core/src/option.rs Co-authored-by: Ivan Tham --- library/core/src/option.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 4e8a74d9162a5..a3d20f016fd98 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -562,10 +562,6 @@ impl Option { } } - ///////////////////////////////////////////////////////////////////////// - // Setting a new value - ///////////////////////////////////////////////////////////////////////// - /// Inserts `value` into the option then returns a mutable reference to it. /// /// If the option already contains a value, the old value is dropped. From 216d0fe36466ce9307a643a67afa41ebfb8c43dd Mon Sep 17 00:00:00 2001 From: Canop Date: Fri, 23 Oct 2020 11:44:58 +0200 Subject: [PATCH 12/13] add tracking issue number to option_insert feature gate --- library/core/src/option.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/option.rs b/library/core/src/option.rs index a3d20f016fd98..3daf26208b937 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -581,7 +581,7 @@ impl Option { /// assert_eq!(opt.unwrap(), 3); /// ``` #[inline] - #[unstable(feature = "option_insert", reason = "newly added", issue = "none")] + #[unstable(feature = "option_insert", reason = "newly added", issue = "78271")] pub fn insert(&mut self, value: T) -> &mut T { *self = Some(value); From efedcb23447a805fad841c4e38d5dea0d53ec3c7 Mon Sep 17 00:00:00 2001 From: Eduardo Pinho Date: Fri, 23 Oct 2020 12:13:07 +0100 Subject: [PATCH 13/13] Update description of Empty Enum for accuracy An empty enum is similar to the never type `!`, rather than the unit type `()`. --- library/std/src/keyword_docs.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/keyword_docs.rs b/library/std/src/keyword_docs.rs index a4bbb18da5983..9b704ee9ecab2 100644 --- a/library/std/src/keyword_docs.rs +++ b/library/std/src/keyword_docs.rs @@ -346,7 +346,7 @@ mod else_keyword {} /// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data /// is added as the type describes, for example `Option::Some(123)`. The same follows with /// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff: -/// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be +/// true, blah: "hello!".to_string(), }`. Empty Enums are similar to [`!`] in that they cannot be /// instantiated at all, and are used mainly to mess with the type system in interesting ways. /// /// For more information, take a look at the [Rust Book] or the [Reference] @@ -354,6 +354,7 @@ mod else_keyword {} /// [ADT]: https://en.wikipedia.org/wiki/Algebraic_data_type /// [Rust Book]: ../book/ch06-01-defining-an-enum.html /// [Reference]: ../reference/items/enumerations.html +/// [`!`]: primitive.never.html mod enum_keyword {} #[doc(keyword = "extern")]