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.
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.
11 use rustc
::infer
::InferCtxt
;
12 use rustc
::infer
::canonical
::{CanonicalVarValues, Canonicalize, Certainty, QueryResult}
;
13 use rustc
::infer
::region_constraints
::{Constraint, RegionConstraintData}
;
14 use rustc
::traits
::{FulfillmentContext, TraitEngine}
;
15 use rustc
::traits
::query
::NoSolution
;
19 /// The canonicalization form of `QueryResult<'tcx, T>`.
20 type CanonicalizedQueryResult
<'gcx
, 'tcx
, T
> =
21 <QueryResult
<'tcx
, T
> as Canonicalize
<'gcx
, 'tcx
>>::Canonicalized
;
23 crate fn make_query_response
<'gcx
, 'tcx
, T
>(
24 infcx
: &InferCtxt
<'_
, 'gcx
, 'tcx
>,
25 inference_vars
: CanonicalVarValues
<'tcx
>,
27 fulfill_cx
: &mut FulfillmentContext
<'tcx
>,
28 ) -> Result
<CanonicalizedQueryResult
<'gcx
, 'tcx
, T
>, NoSolution
>
31 QueryResult
<'tcx
, T
>: Canonicalize
<'gcx
, 'tcx
>,
36 "make_query_response(\
37 inference_vars={:?}, \
39 inference_vars
, answer
,
42 // Select everything, returning errors.
43 let true_errors
= match fulfill_cx
.select_where_possible(infcx
) {
45 Err(errors
) => errors
,
47 debug
!("true_errors = {:#?}", true_errors
);
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
);
55 // Anything left unselected *now* must be an ambiguity.
56 let ambig_errors
= match fulfill_cx
.select_all_or_error(infcx
) {
58 Err(errors
) => errors
,
60 debug
!("ambig_errors = {:#?}", ambig_errors
);
62 let region_obligations
= infcx
.take_registered_region_obligations();
64 let region_constraints
= infcx
.with_region_constraints(|region_constraints
| {
65 let RegionConstraintData
{
69 } = region_constraints
;
71 assert
!(verifys
.is_empty());
72 assert
!(givens
.is_empty());
74 let mut outlives
: Vec
<_
> = constraints
76 .map(|(k
, _
)| match *k
{
77 Constraint
::VarSubVar(v1
, v2
) => ty
::OutlivesPredicate(
78 tcx
.mk_region(ty
::ReVar(v1
)).into(),
79 tcx
.mk_region(ty
::ReVar(v2
)),
81 Constraint
::VarSubReg(v1
, r2
) => {
82 ty
::OutlivesPredicate(tcx
.mk_region(ty
::ReVar(v1
)).into(), r2
)
84 Constraint
::RegSubVar(r1
, v2
) => {
85 ty
::OutlivesPredicate(r1
.into(), tcx
.mk_region(ty
::ReVar(v2
)))
87 Constraint
::RegSubReg(r1
, r2
) => ty
::OutlivesPredicate(r1
.into(), r2
),
89 .map(ty
::Binder
::dummy
) // no bound regions in the code above
95 .map(|(_
, r_o
)| ty
::OutlivesPredicate(r_o
.sup_type
.into(), r_o
.sub_region
))
96 .map(ty
::Binder
::dummy
) // no bound regions in the code above
102 let certainty
= if ambig_errors
.is_empty() {
108 let (canonical_result
, _
) = infcx
.canonicalize_response(&QueryResult
{
109 var_values
: inference_vars
,
116 "make_query_response: canonical_result = {:#?}",