]> git.proxmox.com Git - rustc.git/blame - src/librustc_traits/util.rs
New upstream version 1.28.0~beta.14+dfsg1
[rustc.git] / src / librustc_traits / util.rs
CommitLineData
0531ce1d
XL
1// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2// file at the top-level directory of this distribution and at
3// http://rust-lang.org/COPYRIGHT.
4//
5// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8// option. This file may not be copied, modified, or distributed
9// except according to those terms.
10
11use rustc::infer::InferCtxt;
83c7162d 12use rustc::infer::canonical::{CanonicalVarValues, Canonicalize, Certainty, QueryResult};
0531ce1d
XL
13use rustc::infer::region_constraints::{Constraint, RegionConstraintData};
14use rustc::traits::{FulfillmentContext, TraitEngine};
15use rustc::traits::query::NoSolution;
16use rustc::ty;
17use std::fmt::Debug;
18
19/// The canonicalization form of `QueryResult<'tcx, T>`.
20type CanonicalizedQueryResult<'gcx, 'tcx, T> =
21 <QueryResult<'tcx, T> as Canonicalize<'gcx, 'tcx>>::Canonicalized;
22
23crate fn make_query_response<'gcx, 'tcx, T>(
24 infcx: &InferCtxt<'_, 'gcx, 'tcx>,
25 inference_vars: CanonicalVarValues<'tcx>,
26 answer: T,
27 fulfill_cx: &mut FulfillmentContext<'tcx>,
28) -> Result<CanonicalizedQueryResult<'gcx, 'tcx, T>, NoSolution>
29where
30 T: Debug,
31 QueryResult<'tcx, T>: Canonicalize<'gcx, 'tcx>,
32{
33 let tcx = infcx.tcx;
34
35 debug!(
36 "make_query_response(\
37 inference_vars={:?}, \
38 answer={:?})",
39 inference_vars, answer,
40 );
41
42 // Select everything, returning errors.
43 let true_errors = match fulfill_cx.select_where_possible(infcx) {
44 Ok(()) => vec![],
45 Err(errors) => errors,
46 };
47 debug!("true_errors = {:#?}", true_errors);
48
49 if !true_errors.is_empty() {
50 // FIXME -- we don't indicate *why* we failed to solve
51 debug!("make_query_response: true_errors={:#?}", true_errors);
52 return Err(NoSolution);
53 }
54
55 // Anything left unselected *now* must be an ambiguity.
56 let ambig_errors = match fulfill_cx.select_all_or_error(infcx) {
57 Ok(()) => vec![],
58 Err(errors) => errors,
59 };
60 debug!("ambig_errors = {:#?}", ambig_errors);
61
62 let region_obligations = infcx.take_registered_region_obligations();
63
83c7162d 64 let region_constraints = infcx.with_region_constraints(|region_constraints| {
0531ce1d
XL
65 let RegionConstraintData {
66 constraints,
67 verifys,
68 givens,
69 } = region_constraints;
70
71 assert!(verifys.is_empty());
72 assert!(givens.is_empty());
73
83c7162d 74 let mut outlives: Vec<_> = constraints
0531ce1d
XL
75 .into_iter()
76 .map(|(k, _)| match *k {
94b46f34
XL
77 // Swap regions because we are going from sub (<=) to outlives
78 // (>=).
83c7162d 79 Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate(
94b46f34
XL
80 tcx.mk_region(ty::ReVar(v2)).into(),
81 tcx.mk_region(ty::ReVar(v1)),
83c7162d
XL
82 ),
83 Constraint::VarSubReg(v1, r2) => {
94b46f34 84 ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1)))
0531ce1d 85 }
83c7162d 86 Constraint::RegSubVar(r1, v2) => {
94b46f34 87 ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1)
83c7162d 88 }
94b46f34 89 Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1),
0531ce1d 90 })
83c7162d 91 .map(ty::Binder::dummy) // no bound regions in the code above
0531ce1d
XL
92 .collect();
93
83c7162d
XL
94 outlives.extend(
95 region_obligations
96 .into_iter()
97 .map(|(_, r_o)| ty::OutlivesPredicate(r_o.sup_type.into(), r_o.sub_region))
98 .map(ty::Binder::dummy) // no bound regions in the code above
99 );
0531ce1d 100
83c7162d 101 outlives
0531ce1d
XL
102 });
103
104 let certainty = if ambig_errors.is_empty() {
105 Certainty::Proven
106 } else {
107 Certainty::Ambiguous
108 };
109
110 let (canonical_result, _) = infcx.canonicalize_response(&QueryResult {
111 var_values: inference_vars,
83c7162d 112 region_constraints,
0531ce1d
XL
113 certainty,
114 value: answer,
115 });
116
117 debug!(
118 "make_query_response: canonical_result = {:#?}",
119 canonical_result
120 );
121
122 Ok(canonical_result)
123}