fix gencode
[hiphop-php.git] / hphp / hack / src / rupro / hackrs / inference / solve.rs
blobbe13857f0173ffe876a945dd53a412e951a5bd2d
1 // Copyright (c) Meta Platforms, Inc. and affiliates.
2 //
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the "hack" directory of this source tree.
6 #![allow(unused_imports, unused_variables, dead_code)]
7 use crate::inference_env::InferenceEnv;
8 use std::ops::Deref;
9 use ty::local::{Ty, Ty_, Tyvar};
10 use ty::reason::Reason;
12 pub fn remove_tyvar_from_upper_bound<R: Reason>(
13     env: &mut InferenceEnv<R>,
14     tv: Tyvar,
15     ty: &Ty<R>,
16 ) -> Ty<R> {
17     remove_tyvar_from_upper_bound_help(env, tv, ty).unwrap_or_else(|| Ty::mixed(R::none()))
20 fn remove_tyvar_from_upper_bound_help<R: Reason>(
21     env: &mut InferenceEnv<R>,
22     tv: Tyvar,
23     ty: &Ty<R>,
24 ) -> Option<Ty<R>> {
25     use Ty_::*;
26     let ty = env.resolve_ty(ty);
27     match ty.deref() {
28         Tvar(tv2) if tv == *tv2 => None,
29         Toption(ty2) => {
30             let ety2 = remove_tyvar_from_upper_bound_help(env, tv, ty2)?;
31             Some(Ty::option(ty.reason().clone(), ety2))
32         }
33         Tunion(tys) => {
34             let tys_out = tys
35                 .iter()
36                 .map(|ty| remove_tyvar_from_upper_bound_help(env, tv, ty))
37                 .collect::<Option<_>>()?;
38             Some(Ty::union(ty.reason().clone(), tys_out))
39         }
40         _ => Some(ty),
41     }
44 pub fn remove_tyvar_from_lower_bound<R: Reason>(
45     env: &mut InferenceEnv<R>,
46     tv: Tyvar,
47     ty: &Ty<R>,
48 ) -> Ty<R> {
49     remove_tyvar_from_lower_bound_help(env, tv, ty).unwrap_or_else(|| Ty::nothing(R::none()))
52 fn remove_tyvar_from_lower_bound_help<R: Reason>(
53     env: &mut InferenceEnv<R>,
54     tv: Tyvar,
55     ty: &Ty<R>,
56 ) -> Option<Ty<R>> {
57     use Ty_::*;
58     let ty = env.resolve_ty(ty);
59     match ty.deref() {
60         Tvar(tv2) if tv == *tv2 => None,
61         Tunion(tys) => {
62             let tys_out = tys
63                 .iter()
64                 .filter_map(|ty| remove_tyvar_from_lower_bound_help(env, tv, ty))
65                 .collect();
66             Some(Ty::union(ty.reason().clone(), tys_out))
67         }
68         _ => Some(ty),
69     }
72 #[cfg(test)]
73 mod tests {
74     use super::*;
75     use pos::NPos;
76     use ty::prop::PropF;
77     use ty::reason::NReason;
78     use utils::core::IdentGen;
80     #[test]
81     fn test_remove_upper() {
82         let mut env = InferenceEnv::default();
83         let gen = IdentGen::new();
85         let tv_0: Tyvar = gen.make().into();
86         let ty_v0 = Ty::var(NReason::none(), tv_0);
87         let tv_1: Tyvar = gen.make().into();
88         let ty_v1 = Ty::var(NReason::none(), tv_1);
89         let ty_no_v0 = Ty::option(
90             NReason::none(),
91             Ty::union(
92                 NReason::none(),
93                 vec![
94                     Ty::int(NReason::none()),
95                     Ty::union(NReason::none(), vec![Ty::float(NReason::none()), ty_v1]),
96                 ],
97             ),
98         );
99         let ty_with_v0 = Ty::option(
100             NReason::none(),
101             Ty::union(
102                 NReason::none(),
103                 vec![
104                     Ty::int(NReason::none()),
105                     Ty::union(NReason::none(), vec![Ty::float(NReason::none()), ty_v0]),
106                 ],
107             ),
108         );
110         assert!(remove_tyvar_from_upper_bound_help(&mut env, tv_0, &ty_no_v0).is_some());
111         assert!(remove_tyvar_from_upper_bound_help(&mut env, tv_0, &ty_with_v0).is_none());
112     }