summary refs log tree commit diff
path: root/src/librustc/traits
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-06-01 20:38:24 +0000
committerbors <bors@rust-lang.org>2018-06-01 20:38:24 +0000
commit594fb253c2b02b320c728391a425d028e6dc7a09 (patch)
tree774dd13bd4cdf23d042ba7c005a4a3f55ac48382 /src/librustc/traits
parent827013a31b88e536e85b8e6ceb5b9988042ec335 (diff)
parent7093b11690486e5fd3502b299b5477a83fd3b001 (diff)
downloadrust-1.26.2.tar.gz
rust-1.26.2.zip
Auto merge of #51258 - Mark-Simulacrum:stable-next, r=nikomatsakis 1.26.2
1.26.2 release

This includes a backport of #51235 which fixes #51117 on stable. It has not been tested.

r? @nikomatsakis since the backport was not clean.
cc @rust-lang/core @rust-lang/release
Diffstat (limited to 'src/librustc/traits')
-rw-r--r--src/librustc/traits/project.rs31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index de336c29229..441089250a1 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -137,17 +137,30 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
     fn push_candidate(&mut self, candidate: ProjectionTyCandidate<'tcx>) -> bool {
         use self::ProjectionTyCandidateSet::*;
         use self::ProjectionTyCandidate::*;
+
+        // This wacky variable is just used to try and
+        // make code readable and avoid confusing paths.
+        // It is assigned a "value" of `()` only on those
+        // paths in which we wish to convert `*self` to
+        // ambiguous (and return false, because the candidate
+        // was not used). On other paths, it is not assigned,
+        // and hence if those paths *could* reach the code that
+        // comes after the match, this fn would not compile.
+        let convert_to_ambigious;
+
         match self {
             None => {
                 *self = Single(candidate);
-                true
+                return true;
             }
+
             Single(current) => {
                 // Duplicates can happen inside ParamEnv. In the case, we
                 // perform a lazy deduplication.
                 if current == &candidate {
                     return false;
                 }
+
                 // Prefer where-clauses. As in select, if there are multiple
                 // candidates, we prefer where-clause candidates over impls.  This
                 // may seem a bit surprising, since impls are the source of
@@ -156,17 +169,23 @@ impl<'tcx> ProjectionTyCandidateSet<'tcx> {
                 // clauses are the safer choice. See the comment on
                 // `select::SelectionCandidate` and #21974 for more details.
                 match (current, candidate) {
-                    (ParamEnv(..), ParamEnv(..)) => { *self = Ambiguous; }
-                    (ParamEnv(..), _) => {}
+                    (ParamEnv(..), ParamEnv(..)) => convert_to_ambigious = (),
+                    (ParamEnv(..), _) => return false,
                     (_, ParamEnv(..)) => { unreachable!(); }
-                    (_, _) => { *self = Ambiguous; }
+                    (_, _) => convert_to_ambigious = (),
                 }
-                false
             }
+
             Ambiguous | Error(..) => {
-                false
+                return false;
             }
         }
+
+        // We only ever get here when we moved from a single candidate
+        // to ambiguous.
+        let () = convert_to_ambigious;
+        *self = Ambiguous;
+        false
     }
 }