]> git.lizzy.rs Git - rust.git/blob - src/librustc/traits/query/type_op/outlives.rs
Rollup merge of #51765 - jonas-schievink:patch-1, r=KodrAus
[rust.git] / src / librustc / traits / query / type_op / outlives.rs
1 // Copyright 2016 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
11 use infer::canonical::{Canonical, Canonicalized, CanonicalizedQueryResult, QueryResult};
12 use traits::query::dropck_outlives::trivial_dropck_outlives;
13 use traits::query::dropck_outlives::DropckOutlivesResult;
14 use traits::query::Fallible;
15 use ty::{ParamEnvAnd, Ty, TyCtxt};
16
17 #[derive(Copy, Clone, Debug)]
18 pub struct DropckOutlives<'tcx> {
19     dropped_ty: Ty<'tcx>,
20 }
21
22 impl<'tcx> DropckOutlives<'tcx> {
23     pub fn new(dropped_ty: Ty<'tcx>) -> Self {
24         DropckOutlives { dropped_ty }
25     }
26 }
27
28 impl super::QueryTypeOp<'gcx, 'tcx> for DropckOutlives<'tcx>
29 where
30     'gcx: 'tcx,
31 {
32     type QueryResult = DropckOutlivesResult<'tcx>;
33
34     fn try_fast_path(
35         tcx: TyCtxt<'_, 'gcx, 'tcx>,
36         key: &ParamEnvAnd<'tcx, Self>,
37     ) -> Option<Self::QueryResult> {
38         if trivial_dropck_outlives(tcx, key.value.dropped_ty) {
39             Some(DropckOutlivesResult::default())
40         } else {
41             None
42         }
43     }
44
45     fn perform_query(
46         tcx: TyCtxt<'_, 'gcx, 'tcx>,
47         canonicalized: Canonicalized<'gcx, ParamEnvAnd<'tcx, Self>>,
48     ) -> Fallible<CanonicalizedQueryResult<'gcx, Self::QueryResult>> {
49         // Subtle: note that we are not invoking
50         // `infcx.at(...).dropck_outlives(...)` here, but rather the
51         // underlying `dropck_outlives` query. This same underlying
52         // query is also used by the
53         // `infcx.at(...).dropck_outlives(...)` fn. Avoiding the
54         // wrapper means we don't need an infcx in this code, which is
55         // good because the interface doesn't give us one (so that we
56         // know we are not registering any subregion relations or
57         // other things).
58
59         // FIXME convert to the type expected by the `dropck_outlives`
60         // query. This should eventually be fixed by changing the
61         // *underlying query*.
62         let Canonical {
63             variables,
64             value:
65                 ParamEnvAnd {
66                     param_env,
67                     value: DropckOutlives { dropped_ty },
68                 },
69         } = canonicalized;
70         let canonicalized = Canonical {
71             variables,
72             value: param_env.and(dropped_ty),
73         };
74
75         tcx.dropck_outlives(canonicalized)
76     }
77
78     fn shrink_to_tcx_lifetime(
79         lifted_query_result: &'a CanonicalizedQueryResult<'gcx, Self::QueryResult>,
80     ) -> &'a Canonical<'tcx, QueryResult<'tcx, Self::QueryResult>> {
81         lifted_query_result
82     }
83 }
84
85 BraceStructTypeFoldableImpl! {
86     impl<'tcx> TypeFoldable<'tcx> for DropckOutlives<'tcx> {
87         dropped_ty
88     }
89 }
90
91 BraceStructLiftImpl! {
92     impl<'a, 'tcx> Lift<'tcx> for DropckOutlives<'a> {
93         type Lifted = DropckOutlives<'tcx>;
94         dropped_ty
95     }
96 }
97
98 impl_stable_hash_for! {
99     struct DropckOutlives<'tcx> { dropped_ty }
100 }