diff options
| author | bors <bors@rust-lang.org> | 2018-06-01 20:38:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-06-01 20:38:24 +0000 |
| commit | 594fb253c2b02b320c728391a425d028e6dc7a09 (patch) | |
| tree | 774dd13bd4cdf23d042ba7c005a4a3f55ac48382 /src/librustc/traits | |
| parent | 827013a31b88e536e85b8e6ceb5b9988042ec335 (diff) | |
| parent | 7093b11690486e5fd3502b299b5477a83fd3b001 (diff) | |
| download | rust-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.rs | 31 |
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 } } |
